Skip to content

Commit

Permalink
accumulators: correct shape of returned data array.
Browse files Browse the repository at this point in the history
  • Loading branch information
KaiSzuttor committed Mar 12, 2020
1 parent a8e71b2 commit 772a6e6
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 49 deletions.
1 change: 1 addition & 0 deletions src/core/accumulators/MeanVarianceCalculator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MeanVarianceCalculator : public AccumulatorBase {
via the interface. */
std::string get_internal_state() const;
void set_internal_state(std::string const &);
std::vector<std::size_t> shape() const { return m_obs->shape(); }

private:
std::shared_ptr<Observables::Observable> m_obs;
Expand Down
6 changes: 6 additions & 0 deletions src/core/accumulators/TimeSeries.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class TimeSeries : public AccumulatorBase {
void set_internal_state(std::string const &);

const std::vector<std::vector<double>> &time_series() const { return m_data; }
std::vector<std::size_t> shape() const {
std::vector<std::size_t> shape{m_data.size()};
auto obs_shape = m_obs->shape();
shape.insert(shape.end(), obs_shape.begin(), obs_shape.end());
return shape;
}
void clear() { m_data.clear(); }

private:
Expand Down
14 changes: 11 additions & 3 deletions src/python/espressomd/accumulators.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,16 @@ class MeanVarianceCalculator(ScriptInterfaceHelper):
_so_name = "Accumulators::MeanVarianceCalculator"
_so_bind_methods = (
"update",
"get_mean",
"get_variance"
"shape",
)
_so_creation_policy = "LOCAL"

def get_mean(self):
return np.array(self.call_method("get_mean")).reshape(self.shape())

def get_variance(self):
return np.array(self.call_method("get_variance")).reshape(self.shape())


@script_interface_register
class TimeSeries(ScriptInterfaceHelper):
Expand All @@ -75,11 +80,14 @@ class TimeSeries(ScriptInterfaceHelper):
_so_name = "Accumulators::TimeSeries"
_so_bind_methods = (
"update",
"time_series",
"shape",
"clear"
)
_so_creation_policy = "LOCAL"

def time_series(self):
return np.array(self.call_method("time_series")).reshape(self.shape())


@script_interface_register
class Correlator(ScriptInterfaceHelper):
Expand Down
4 changes: 4 additions & 0 deletions src/script_interface/accumulators/MeanVarianceCalculator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class MeanVarianceCalculator : public AccumulatorBase {

if (method == "get_variance")
return mean_variance_calculator()->get_variance();
if (method == "shape") {
auto const shape = m_accumulator->shape();
return std::vector<int>{shape.begin(), shape.end()};
}
return {};
}

Expand Down
4 changes: 4 additions & 0 deletions src/script_interface/accumulators/TimeSeries.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class TimeSeries : public AccumulatorBase {
m_accumulator->clear();
}

if (method == "shape") {
auto const shape = m_accumulator->shape();
return std::vector<int>{shape.begin(), shape.end()};
}
return {};
}

Expand Down
17 changes: 11 additions & 6 deletions testsuite/python/accumulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
import espressomd.accumulators


N_PART = 4


class AccumulatorTest(ut.TestCase):

"""
Expand All @@ -41,24 +44,26 @@ def setUp(self):
self.system = espressomd.System(box_l=[10.0] * 3)
self.system.cell_system.skin = 0.4
self.system.time_step = 0.01
self.system.part.add(id=0, pos=[0.0, 0.0, 0.0])
self.system.part.add(pos=np.zeros((N_PART, 3)))
self.system.integrator.run(steps=0)
self.pos_obs = espressomd.observables.ParticlePositions(ids=(0,))
self.pos_obs = espressomd.observables.ParticlePositions(ids=range(N_PART))
self.pos_obs_acc = espressomd.accumulators.MeanVarianceCalculator(
obs=self.pos_obs)
self.system.auto_update_accumulators.add(self.pos_obs_acc)
self.positions = np.copy(self.system.box_l * np.random.rand(10, 3))
self.positions = np.copy(self.system.box_l) * \
np.random.random((10, N_PART, 3))

def test_accumulator(self):
"""Check that accumulator results are the same as the respective numpy result.
"""
for i in range(self.positions.shape[0]):
self.system.part[0].pos = self.positions[i]
for pos in self.positions:
self.system.part[:].pos = pos
self.system.integrator.run(1)
self.assertEqual(self.pos_obs, self.pos_obs_acc.get_params()['obs'])
acc_mean = self.pos_obs_acc.get_mean()
np.testing.assert_allclose(
self.pos_obs_acc.get_mean(),
acc_mean,
np.mean(self.positions, axis=0), atol=1e-4)
np.testing.assert_allclose(
self.pos_obs_acc.get_variance(),
Expand Down
39 changes: 21 additions & 18 deletions testsuite/python/brownian_dynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,29 +273,32 @@ def test_08__noise_correlation(self):

# test translational noise correlation
vel = np.array(vel_series.time_series())
for i in range(6):
for j in range(i, 6):
corrcoef = np.dot(vel[:, i], vel[:, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
self.assertLessEqual(np.abs(corrcoef), 0.04)
for ind in range(2):
for i in range(3):
for j in range(i, 3):
corrcoef = np.dot(
vel[:, ind, i], vel[:, ind, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
self.assertLessEqual(np.abs(corrcoef), 0.04)

# test rotational noise correlation
if espressomd.has_features("ROTATION"):
omega = np.array(omega_series.time_series())
for i in range(6):
for j in range(6):
corrcoef = np.dot(omega[:, i], omega[:, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
for ind in range(2):
for i in range(3):
for j in range(3):
corrcoef = np.dot(
omega[:, ind, i], omega[:, ind, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
self.assertLessEqual(np.abs(corrcoef), 0.04)
# translational and angular velocities should be independent
corrcoef = np.dot(
vel[:, ind, i], omega[:, ind, j]) / steps / kT
self.assertLessEqual(np.abs(corrcoef), 0.04)
# translational and angular velocities should be independent
for i in range(6):
for j in range(6):
corrcoef = np.dot(vel[:, i], omega[:, j]) / steps / kT
self.assertLessEqual(np.abs(corrcoef), 0.04)


if __name__ == "__main__":
Expand Down
39 changes: 21 additions & 18 deletions testsuite/python/langevin_thermostat.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,29 +522,32 @@ def test_08__noise_correlation(self):

# test translational noise correlation
vel = np.array(vel_series.time_series())
for i in range(6):
for j in range(i, 6):
corrcoef = np.dot(vel[:, i], vel[:, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
self.assertLessEqual(np.abs(corrcoef), 0.04)
for ind in range(2):
for i in range(3):
for j in range(i, 3):
corrcoef = np.dot(
vel[:, ind, i], vel[:, ind, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
self.assertLessEqual(np.abs(corrcoef), 0.04)

# test rotational noise correlation
if espressomd.has_features("ROTATION"):
omega = np.array(omega_series.time_series())
for i in range(6):
for j in range(6):
corrcoef = np.dot(omega[:, i], omega[:, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
for ind in range(2):
for i in range(3):
for j in range(3):
corrcoef = np.dot(
omega[:, ind, i], omega[:, ind, j]) / steps / kT
if i == j:
self.assertAlmostEqual(corrcoef, 1.0, delta=0.04)
else:
self.assertLessEqual(np.abs(corrcoef), 0.04)
# translational and angular velocities should be independent
corrcoef = np.dot(
vel[:, ind, i], omega[:, ind, j]) / steps / kT
self.assertLessEqual(np.abs(corrcoef), 0.04)
# translational and angular velocities should be independent
for i in range(6):
for j in range(6):
corrcoef = np.dot(vel[:, i], omega[:, j]) / steps / kT
self.assertLessEqual(np.abs(corrcoef), 0.04)


if __name__ == "__main__":
Expand Down
6 changes: 3 additions & 3 deletions testsuite/python/test_checkpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,12 @@ def test_virtual_sites(self):

def test_mean_variance_calculator(self):
np.testing.assert_array_equal(
acc.get_mean(), np.array([1.0, 1.5, 2.0, 1.0, 1.0, 2.0]))
acc.get_mean(), np.array([[1.0, 1.5, 2.0], [1.0, 1.0, 2.0]]))
np.testing.assert_array_equal(
acc.get_variance(), np.array([0., 0.5, 2., 0., 0., 0.]))
acc.get_variance(), np.array([[0., 0.5, 2.], [0., 0., 0.]]))
np.testing.assert_array_equal(
system.auto_update_accumulators[0].get_variance(),
np.array([0., 0.5, 2., 0., 0., 0.]))
np.array([[0., 0.5, 2.], [0., 0., 0.]]))

@utx.skipIfMissingFeatures('P3M')
@ut.skipIf('P3M.CPU' not in modes,
Expand Down
2 changes: 1 addition & 1 deletion testsuite/python/time_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def test_time_series(self):

for result, expected in zip(time_series.time_series(), positions):
np.testing.assert_array_equal(
np.array(result).reshape((N_PART, 3)), expected)
result, expected)

time_series.clear()
self.assertEqual(len(time_series.time_series()), 0)
Expand Down

0 comments on commit 772a6e6

Please sign in to comment.