refactor: removes redundant calculation and uses pdme
This commit is contained in:
parent
df4d0b5d15
commit
62bd63bf9b
@ -54,109 +54,13 @@ class SingleDotSpinQubitFrequencyFilter(DirectMonteCarloFilter):
|
|||||||
self.measurements
|
self.measurements
|
||||||
)
|
)
|
||||||
|
|
||||||
# oh no not this again
|
|
||||||
def fast_s_spin_qubit_tarucha_apsd_dipoleses(
|
|
||||||
self, dot_inputs: numpy.ndarray, dipoleses: numpy.ndarray
|
|
||||||
) -> numpy.ndarray:
|
|
||||||
"""
|
|
||||||
No error correction here baby.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# We're going to annotate the indices on this class.
|
|
||||||
# Let's define some indices:
|
|
||||||
# A -> index of dipoleses configurations
|
|
||||||
# j -> within a particular configuration, indexes dipole j
|
|
||||||
# measurement_index -> if we have 100 frequencies for example, indexes which one of them it is
|
|
||||||
# If we need to use numbers, let's use A -> 2, j -> 10, measurement_index -> 9 for consistency with
|
|
||||||
# my other notes
|
|
||||||
|
|
||||||
# axes are [dipole_config_idx A, dipole_idx j, {px, py, pz}3]
|
|
||||||
ps = dipoleses[:, :, 0:3]
|
|
||||||
# axes are [dipole_config_idx A, dipole_idx j, {sx, sy, sz}3]
|
|
||||||
ss = dipoleses[:, :, 3:6]
|
|
||||||
# axes are [dipole_config_idx A, dipole_idx j, w], last axis is just 1
|
|
||||||
ws = dipoleses[:, :, 6]
|
|
||||||
|
|
||||||
# dot_index is either 0 or 1 for dot1 or dot2
|
|
||||||
# hopefully this adhoc grammar is making sense, with the explicit labelling of the values of the last axis in cartesian space
|
|
||||||
# axes are [measurement_idx, {dot_index}, {rx, ry, rz}] where the inner {dot_index} is gone
|
|
||||||
# [measurement_idx, cartesian3]
|
|
||||||
rs = dot_inputs[:, 0:3]
|
|
||||||
# axes are [measurement_idx]
|
|
||||||
fs = dot_inputs[:, 3]
|
|
||||||
|
|
||||||
# first operation!
|
|
||||||
# r1s has shape [measurement_idx, rxs]
|
|
||||||
# None inserts an extra axis so the r1s[:, None] has shape
|
|
||||||
# [measurement_idx, 1]([rxs]) with the last rxs hidden
|
|
||||||
#
|
|
||||||
# ss has shape [ A, j, {sx, sy, sz}3], so second term has shape [A, 1, j]([sxs])
|
|
||||||
# these broadcast from right to left
|
|
||||||
# [ measurement_idx, 1, rxs]
|
|
||||||
# [A, 1, j, sxs]
|
|
||||||
# resulting in [A, measurement_idx, j, cart3] sxs rxs are both cart3
|
|
||||||
diffses = rs[:, None] - ss[:, None, :]
|
|
||||||
|
|
||||||
# norms takes out axis 3, the last one, giving [A, measurement_idx, j]
|
|
||||||
norms = numpy.linalg.norm(diffses, axis=3)
|
|
||||||
|
|
||||||
# _logger.info(f"norms1: {norms1}")
|
|
||||||
# _logger.info(f"norms1 shape: {norms1.shape}")
|
|
||||||
#
|
|
||||||
# diffses1 (A, measurement_idx, j, xs)
|
|
||||||
# ps: (A, j, px)
|
|
||||||
# result is (A, measurement_idx, j)
|
|
||||||
# intermediate_dot_prod = numpy.einsum("abcd,acd->abc", diffses1, ps)
|
|
||||||
# _logger.info(f"dot product shape: {intermediate_dot_prod.shape}")
|
|
||||||
|
|
||||||
# transpose makes it (j, measurement_idx, A)
|
|
||||||
# transp_intermediate_dot_prod = numpy.transpose(numpy.einsum("abcd,acd->abc", diffses1, ps) / (norms1**3))
|
|
||||||
|
|
||||||
# transpose of diffses has shape (xs, j, measurement_idx, A)
|
|
||||||
# numpy.transpose(diffses1)
|
|
||||||
# _logger.info(f"dot product shape: {transp_intermediate_dot_prod.shape}")
|
|
||||||
|
|
||||||
# inner transpose is (j, measurement_idx, A) * (xs, j, measurement_idx, A)
|
|
||||||
# next transpose puts it back to (A, measurement_idx, j, xs)
|
|
||||||
# p_dot_r_times_r_term = 3 * numpy.transpose(numpy.transpose(numpy.einsum("abcd,acd->abc", diffses1, ps) / (norms1**3)) * numpy.transpose(diffses1))
|
|
||||||
# _logger.info(f"p_dot_r_times_r_term: {p_dot_r_times_r_term.shape}")
|
|
||||||
|
|
||||||
# only x axis puts us at (A, measurement_idx, j)
|
|
||||||
# p_dot_r_times_r_term_x_only = p_dot_r_times_r_term[:, :, :, 0]
|
|
||||||
# _logger.info(f"p_dot_r_times_r_term_x_only.shape: {p_dot_r_times_r_term_x_only.shape}")
|
|
||||||
|
|
||||||
# now to complete the numerator we subtract the ps, which are (A, j, px):
|
|
||||||
# slicing off the end gives us (A, j), so we newaxis to get (A, 1, j)
|
|
||||||
# _logger.info(ps[:, numpy.newaxis, :, 0].shape)
|
|
||||||
alphses = (
|
|
||||||
(
|
|
||||||
3
|
|
||||||
* numpy.transpose(
|
|
||||||
numpy.transpose(
|
|
||||||
numpy.einsum("abcd,acd->abc", diffses, ps) / (norms**2)
|
|
||||||
)
|
|
||||||
* numpy.transpose(diffses)
|
|
||||||
)[:, :, :, 0]
|
|
||||||
)
|
|
||||||
- ps[:, numpy.newaxis, :, 0]
|
|
||||||
) / (norms**3)
|
|
||||||
|
|
||||||
bses = (
|
|
||||||
2
|
|
||||||
* numpy.pi
|
|
||||||
* ws[:, None, :]
|
|
||||||
/ ((2 * numpy.pi * fs[:, None]) ** 2 + 4 * ws[:, None, :] ** 2)
|
|
||||||
)
|
|
||||||
|
|
||||||
return numpy.einsum("...j->...", alphses * alphses * bses)
|
|
||||||
|
|
||||||
def filter_samples(self, samples: ndarray) -> ndarray:
|
def filter_samples(self, samples: ndarray) -> ndarray:
|
||||||
current_sample = samples
|
current_sample = samples
|
||||||
for di, low, high in zip(self.dot_inputs_array, self.lows, self.highs):
|
for di, low, high in zip(self.dot_inputs_array, self.lows, self.highs):
|
||||||
|
|
||||||
if len(current_sample) < 1:
|
if len(current_sample) < 1:
|
||||||
break
|
break
|
||||||
vals = self.fast_s_spin_qubit_tarucha_apsd_dipoleses(
|
vals = pdme.util.fast_v_calc.fast_efieldxs_for_dipoleses(
|
||||||
numpy.array([di]), current_sample
|
numpy.array([di]), current_sample
|
||||||
)
|
)
|
||||||
# _logger.info(vals)
|
# _logger.info(vals)
|
||||||
|
0
tests/direct_monte_carlo/__init__.py
Normal file
0
tests/direct_monte_carlo/__init__.py
Normal file
137
tests/direct_monte_carlo/test_eletric_field_x_dmc_filter.py
Normal file
137
tests/direct_monte_carlo/test_eletric_field_x_dmc_filter.py
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import pdme.measurement
|
||||||
|
import pdme.measurement.input_types
|
||||||
|
from pdme.model import (
|
||||||
|
LogSpacedRandomCountMultipleDipoleFixedMagnitudeModel,
|
||||||
|
LogSpacedRandomCountMultipleDipoleFixedMagnitudeXYModel,
|
||||||
|
LogSpacedRandomCountMultipleDipoleFixedMagnitudeFixedOrientationModel,
|
||||||
|
)
|
||||||
|
import deepdog.direct_monte_carlo.dmc_filters
|
||||||
|
import numpy.random
|
||||||
|
import numpy.testing
|
||||||
|
import logging
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def fixed_z_model_func(
|
||||||
|
xmin,
|
||||||
|
xmax,
|
||||||
|
ymin,
|
||||||
|
ymax,
|
||||||
|
zmin,
|
||||||
|
zmax,
|
||||||
|
wexp_min,
|
||||||
|
wexp_max,
|
||||||
|
pfixed,
|
||||||
|
n_max,
|
||||||
|
prob_occupancy,
|
||||||
|
):
|
||||||
|
return LogSpacedRandomCountMultipleDipoleFixedMagnitudeFixedOrientationModel(
|
||||||
|
xmin,
|
||||||
|
xmax,
|
||||||
|
ymin,
|
||||||
|
ymax,
|
||||||
|
zmin,
|
||||||
|
zmax,
|
||||||
|
wexp_min,
|
||||||
|
wexp_max,
|
||||||
|
pfixed,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
n_max,
|
||||||
|
prob_occupancy,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_model(orientation):
|
||||||
|
model_funcs = {
|
||||||
|
"fixedz": fixed_z_model_func,
|
||||||
|
"free": LogSpacedRandomCountMultipleDipoleFixedMagnitudeModel,
|
||||||
|
"fixedxy": LogSpacedRandomCountMultipleDipoleFixedMagnitudeXYModel,
|
||||||
|
}
|
||||||
|
model = model_funcs[orientation](
|
||||||
|
-10,
|
||||||
|
10,
|
||||||
|
-17.5,
|
||||||
|
17.5,
|
||||||
|
5,
|
||||||
|
7.5,
|
||||||
|
-5,
|
||||||
|
6.5,
|
||||||
|
10**3,
|
||||||
|
2,
|
||||||
|
0.99999999,
|
||||||
|
)
|
||||||
|
model.n = 2
|
||||||
|
model.rng = numpy.random.default_rng(1234)
|
||||||
|
|
||||||
|
return (
|
||||||
|
f"connors_geom-5height-orientation_{orientation}-pfixexp_{3}-dipole_count_{2}",
|
||||||
|
model,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_electric_field_x_dmc_filter():
|
||||||
|
|
||||||
|
dipoles_raw = [
|
||||||
|
[(1, 2, 3), (4, 5, 6), 1],
|
||||||
|
[(-1, 5, 2), (6, 5, 4), 10],
|
||||||
|
]
|
||||||
|
dipoles = [
|
||||||
|
pdme.measurement.OscillatingDipole(numpy.array(d[0]), numpy.array(d[1]), d[2])
|
||||||
|
for d in dipoles_raw
|
||||||
|
]
|
||||||
|
|
||||||
|
_logger.debug(f"dipoles: {dipoles}")
|
||||||
|
dot_inputs_raw = [
|
||||||
|
([-1, -1, 0], 1),
|
||||||
|
([-1, -1, 0], 2),
|
||||||
|
([-1, -1, 0], 3),
|
||||||
|
([-1, -1, 0], 4),
|
||||||
|
]
|
||||||
|
dot_inputs_array = pdme.measurement.input_types.dot_inputs_to_array(dot_inputs_raw)
|
||||||
|
_logger.debug(f"dot_inputs_array: {dot_inputs_array}")
|
||||||
|
|
||||||
|
arrangement = pdme.measurement.OscillatingDipoleArrangement(dipoles)
|
||||||
|
measurements = []
|
||||||
|
for input in dot_inputs_raw:
|
||||||
|
ex = sum(
|
||||||
|
[
|
||||||
|
dipole.s_electric_fieldx_at_position(*input)
|
||||||
|
for dipole in arrangement.dipoles
|
||||||
|
]
|
||||||
|
)
|
||||||
|
ex_low = ex * 0.5
|
||||||
|
ex_high = ex * 1.5
|
||||||
|
meas = pdme.measurement.DotRangeMeasurement(ex_low, ex_high, input[0], input[1])
|
||||||
|
measurements.append(meas)
|
||||||
|
|
||||||
|
filter = deepdog.direct_monte_carlo.dmc_filters.SingleDotSpinQubitFrequencyFilter(
|
||||||
|
measurements
|
||||||
|
)
|
||||||
|
|
||||||
|
samples = numpy.array(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[1, 2, 3, 4, 5, 6, 1],
|
||||||
|
[-1, 5, 2, 6, 5, 4, 10],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[10, 20, 30, 40, 50, 60, 1],
|
||||||
|
[-1, 5, 2, 6, 5, 4, 1],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[1, 1, 1, 1, 1, 1, 1],
|
||||||
|
[2, 2, 2, 2, 2, 2, 1],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
expected = samples[
|
||||||
|
0:1
|
||||||
|
] # only expect to see the first guy, because that's what generated our thing
|
||||||
|
filtered = filter.filter_samples(samples)
|
||||||
|
assert len(filtered) != len(samples), "Should have filtered some out!"
|
||||||
|
numpy.testing.assert_array_equal(
|
||||||
|
filtered, expected, "The filter should have only returned the first one"
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user