update public distribution
based on internal repository c9a2ac8 2019-01-03 16:04:57 +0100 tagged rev-master-2.0.0
This commit is contained in:
616
tests/test_population.py
Normal file
616
tests/test_population.py
Normal file
@@ -0,0 +1,616 @@
|
||||
"""
|
||||
@package tests.test_population
|
||||
unit tests for @ref pmsco.optimizers.population
|
||||
|
||||
the purpose of these tests is to help debugging the code.
|
||||
|
||||
to run the tests, change to the directory which contains the tests directory, and execute =nosetests=.
|
||||
|
||||
@pre nose must be installed (python-nose package on Debian).
|
||||
|
||||
@author Matthias Muntwiler, matthias.muntwiler@psi.ch
|
||||
|
||||
@copyright (c) 2015 by Paul Scherrer Institut @n
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); @n
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
import six
|
||||
|
||||
import numpy as np
|
||||
import os
|
||||
import os.path
|
||||
import random
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import pmsco.optimizers.population as population
|
||||
import pmsco.project as project
|
||||
from pmsco.helpers import BraceMessage as BMsg
|
||||
|
||||
POP_SIZE = 5
|
||||
|
||||
|
||||
class TestPopulation(unittest.TestCase):
|
||||
def setUp(self):
|
||||
random.seed(0)
|
||||
self.test_dir = tempfile.mkdtemp()
|
||||
self.domain = project.Domain()
|
||||
|
||||
self.domain.add_param('A', 1.5, 1.0, 2.0, 0.1)
|
||||
self.domain.add_param('B', 2.5, 2.0, 3.0, 0.1)
|
||||
self.domain.add_param('C', 3.5, 3.0, 4.0, 0.1)
|
||||
self.expected_names = ('_gen', '_model', '_particle', '_rfac', 'A', 'B', 'C')
|
||||
|
||||
self.size = POP_SIZE
|
||||
self.pop = population.Population()
|
||||
|
||||
self.optimum1 = {'A': 1.045351, 'B': 2.346212, 'C': 3.873627}
|
||||
|
||||
def tearDown(self):
|
||||
# after each test method
|
||||
self.pop = None
|
||||
shutil.rmtree(self.test_dir)
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
# before any methods in this class
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
# teardown_class() after any methods in this class
|
||||
pass
|
||||
|
||||
def reorder_pop_array(self, x):
|
||||
"""
|
||||
re-order the columns of a population-like array.
|
||||
|
||||
this makes it easier to create constant arrays with arbitrary column order
|
||||
since population arrays are ordered alphabetically.
|
||||
|
||||
@param x: numpy structured array
|
||||
@return: numpy structured array having the same dtype as the population arrays.
|
||||
"""
|
||||
y = np.zeros(x.shape, dtype=self.pop.get_pop_dtype(self.pop.model_start))
|
||||
for name in y.dtype.names:
|
||||
y[name] = x[name]
|
||||
return y
|
||||
|
||||
def assert_pop_array_equal(self, x, y, msg=""):
|
||||
"""
|
||||
array equality test for population-like structured numpy arrays.
|
||||
|
||||
- check for same column names and kinds
|
||||
- check for same shape
|
||||
- check float columns using np.testing.assert_array_almost_equal
|
||||
- check all other columns using np.testing.assert_array_equal
|
||||
|
||||
@param x: structured numpy array.
|
||||
@param y: structured numpy array.
|
||||
@param msg: optional error message.
|
||||
@return: None
|
||||
@raise AssertionError if arrays are not equal.
|
||||
"""
|
||||
self.assertEqual(x.dtype.names, y.dtype.names, msg=BMsg("{0} (dtype)", msg))
|
||||
self.assertEqual(x.shape, y.shape, msg=BMsg("{0} (shape)", msg))
|
||||
for n, t in x.dtype.fields.items():
|
||||
self.assertEqual(t[0].kind, y.dtype.fields[n][0].kind, msg=BMsg("{0} (column {1} kind)", msg, n))
|
||||
if t[0].kind in {'f', 'c'}:
|
||||
np.testing.assert_array_almost_equal(x[n], y[n], err_msg="{0} (column {1})".format(msg, n))
|
||||
else:
|
||||
np.testing.assert_array_equal(x[n], y[n], err_msg="{0} (column {1})".format(msg, n))
|
||||
|
||||
def rfactor1(self, pos):
|
||||
r = (pos['A'] - self.optimum1['A']) ** 2 \
|
||||
+ (pos['B'] - self.optimum1['B']) ** 2 \
|
||||
+ (pos['C'] - self.optimum1['C']) ** 2
|
||||
r /= 3.0
|
||||
return r
|
||||
|
||||
def test_setup(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
self.assertEqual(self.pop.pos.dtype.names, self.expected_names)
|
||||
self.assertEqual(self.pop.pos.shape, (POP_SIZE,))
|
||||
np.testing.assert_array_equal(np.arange(POP_SIZE), self.pop.pos['_particle'])
|
||||
np.testing.assert_array_equal(np.zeros(POP_SIZE), self.pop.pos['_gen'])
|
||||
np.testing.assert_array_equal(np.arange(POP_SIZE), self.pop.pos['_model'])
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][0], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][1], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][2], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][3], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][4], 3)
|
||||
self.assertEqual(0, self.pop.generation)
|
||||
self.assertEqual(POP_SIZE, self.pop.model_count)
|
||||
|
||||
def test_setup_with_results(self):
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
data_file = os.path.join(data_dir, "test_swarm.setup_with_results.1.dat")
|
||||
self.pop.setup(self.size, self.domain, seed_file=data_file, recalc_seed=False)
|
||||
|
||||
self.assertEqual(self.pop.pos.dtype.names, self.expected_names)
|
||||
self.assertEqual(self.pop.pos.shape, (POP_SIZE,))
|
||||
self.assertEqual(self.pop.generation, 0)
|
||||
self.assertEqual(self.pop.model_count, POP_SIZE)
|
||||
np.testing.assert_array_equal(self.pop.pos['_particle'], np.arange(POP_SIZE))
|
||||
np.testing.assert_array_equal(self.pop.pos['_gen'], [0, 0, -1, 0, 0])
|
||||
np.testing.assert_array_equal(self.pop.pos['_model'], np.arange(POP_SIZE))
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][0], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][1], 3)
|
||||
self.assertAlmostEqual(0.6, self.pop.pos['_rfac'][2], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][3], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][4], 3)
|
||||
self.assertAlmostEqual(1.3, self.pop.pos['A'][1], 3)
|
||||
self.assertAlmostEqual(1.1, self.pop.pos['A'][2], 3)
|
||||
self.assertAlmostEqual(1.5, self.pop.pos['A'][0], 3)
|
||||
self.assertAlmostEqual(2.3, self.pop.pos['B'][1], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['B'][2], 3)
|
||||
self.assertAlmostEqual(2.5, self.pop.pos['B'][0], 3)
|
||||
self.assertGreaterEqual(4.0, self.pop.pos['C'][1], 3)
|
||||
self.assertAlmostEqual(3.1, self.pop.pos['C'][2], 3)
|
||||
self.assertAlmostEqual(3.5, self.pop.pos['C'][0], 3)
|
||||
|
||||
def test_setup_with_results_recalc(self):
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
data_file = os.path.join(data_dir, "test_swarm.setup_with_results.1.dat")
|
||||
self.pop.setup(self.size, self.domain, seed_file=data_file, recalc_seed=True)
|
||||
|
||||
self.assertEqual(self.pop.pos.dtype.names, self.expected_names)
|
||||
self.assertEqual(self.pop.pos.shape, (POP_SIZE,))
|
||||
self.assertEqual(self.pop.generation, 0)
|
||||
self.assertEqual(self.pop.model_count, POP_SIZE)
|
||||
np.testing.assert_array_equal(self.pop.pos['_particle'], np.arange(POP_SIZE))
|
||||
np.testing.assert_array_equal(self.pop.pos['_gen'], [0, 0, 0, 0, 0])
|
||||
np.testing.assert_array_equal(self.pop.pos['_model'], np.arange(POP_SIZE))
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][0], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][1], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][2], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][3], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][4], 3)
|
||||
self.assertAlmostEqual(1.3, self.pop.pos['A'][1], 3)
|
||||
self.assertAlmostEqual(1.1, self.pop.pos['A'][2], 3)
|
||||
self.assertAlmostEqual(1.5, self.pop.pos['A'][0], 3)
|
||||
self.assertAlmostEqual(2.3, self.pop.pos['B'][1], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['B'][2], 3)
|
||||
self.assertAlmostEqual(2.5, self.pop.pos['B'][0], 3)
|
||||
self.assertGreaterEqual(4.0, self.pop.pos['C'][1], 3)
|
||||
self.assertAlmostEqual(3.1, self.pop.pos['C'][2], 3)
|
||||
self.assertAlmostEqual(3.5, self.pop.pos['C'][0], 3)
|
||||
|
||||
def test_setup_with_partial_results(self):
|
||||
self.domain.add_param('D', 4.5, 4.0, 5.0, 0.1)
|
||||
self.expected_names = ('_gen', '_model', '_particle', '_rfac', 'A', 'B', 'C', 'D')
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
data_file = os.path.join(data_dir, "test_swarm.setup_with_results.1.dat")
|
||||
self.pop.setup(self.size, self.domain, seed_file=data_file, recalc_seed=False)
|
||||
|
||||
self.assertEqual(self.pop.pos.dtype.names, self.expected_names)
|
||||
self.assertEqual(self.pop.pos.shape, (POP_SIZE,))
|
||||
self.assertEqual(self.pop.generation, 0)
|
||||
self.assertEqual(self.pop.model_count, POP_SIZE)
|
||||
np.testing.assert_array_equal(self.pop.pos['_particle'], np.arange(POP_SIZE))
|
||||
np.testing.assert_array_equal(self.pop.pos['_gen'], [0, 0, -1, 0, 0])
|
||||
np.testing.assert_array_equal(self.pop.pos['_model'], np.arange(POP_SIZE))
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][0], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][1], 3)
|
||||
self.assertAlmostEqual(0.6, self.pop.pos['_rfac'][2], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][3], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['_rfac'][4], 3)
|
||||
self.assertAlmostEqual(1.3, self.pop.pos['A'][1], 3)
|
||||
self.assertAlmostEqual(1.1, self.pop.pos['A'][2], 3)
|
||||
self.assertAlmostEqual(1.5, self.pop.pos['A'][0], 3)
|
||||
self.assertAlmostEqual(2.3, self.pop.pos['B'][1], 3)
|
||||
self.assertAlmostEqual(2.1, self.pop.pos['B'][2], 3)
|
||||
self.assertAlmostEqual(2.5, self.pop.pos['B'][0], 3)
|
||||
self.assertGreaterEqual(4.0, self.pop.pos['C'][1], 3)
|
||||
self.assertAlmostEqual(3.1, self.pop.pos['C'][2], 3)
|
||||
self.assertAlmostEqual(3.5, self.pop.pos['C'][0], 3)
|
||||
|
||||
def test_pos_gen(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
for index, item in enumerate(self.pop.pos_gen()):
|
||||
self.assertIsInstance(item, dict)
|
||||
self.assertEqual(set(item.keys()), set(self.expected_names))
|
||||
self.assertEqual(item['_particle'], index)
|
||||
|
||||
def test_get_pop_dtype(self):
|
||||
result = population.Population.get_pop_dtype({'A': 1.045, 'C': 3.873, '_D': 4.381, 'B': 2.346})
|
||||
expected = [('_gen', 'i8'), ('_model', 'i8'), ('_particle', 'i8'), ('_rfac', 'f8'),
|
||||
('A', 'f8'), ('B', 'f8'), ('C', 'f8')]
|
||||
self.assertEqual(result, expected)
|
||||
result = population.Population.get_pop_dtype(['A', 'C', '_D', 'B'])
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_get_model_dtype(self):
|
||||
result = population.Population.get_model_dtype({'A': 1.045, 'C': 3.873, '_D': 4.381, 'B': 2.346})
|
||||
expected = [('A', 'f8'), ('B', 'f8'), ('C', 'f8')]
|
||||
self.assertEqual(result, expected)
|
||||
result = population.Population.get_model_dtype(['A', 'C', '_D', 'B'])
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_get_model_array(self):
|
||||
result = population.Population.get_model_array({'A': 1.045, 'C': 3.873, '_D': 4.381, 'B': 2.346})
|
||||
dt = [('A', 'f8'), ('B', 'f8'), ('C', 'f8')]
|
||||
expected = np.array([(1.045, 2.346, 3.873)], dtype=dt)
|
||||
np.testing.assert_array_equal(result, expected)
|
||||
|
||||
def test_randomize(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
self.pop.randomize()
|
||||
m = np.mean(self.pop.pos['A'])
|
||||
self.assertGreaterEqual(m, self.domain.min['A'])
|
||||
self.assertLessEqual(m, self.domain.max['A'])
|
||||
|
||||
def test_seed(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
self.pop.seed(self.domain.start)
|
||||
self.assertAlmostEqual(self.pop.pos['A'][0], self.domain.start['A'], delta=0.001)
|
||||
|
||||
def test_add_result(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
i_sample = 1
|
||||
i_result = 0
|
||||
result = self.pop.pos[i_sample]
|
||||
self.pop.add_result(result, 0.0)
|
||||
self.assertEqual(self.pop.results.shape[0], 1)
|
||||
self.assertEqual(self.pop.results[i_result], result)
|
||||
self.assertEqual(self.pop.best[i_sample], result)
|
||||
|
||||
def test_save_population(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
filename = os.path.join(self.test_dir, "test_save_population.pop")
|
||||
self.pop.save_population(filename)
|
||||
|
||||
def test_save_results(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
i_sample = 1
|
||||
result = self.pop.pos[i_sample]
|
||||
self.pop.add_result(result, 1.0)
|
||||
filename = os.path.join(self.test_dir, "test_save_results.dat")
|
||||
self.pop.save_results(filename)
|
||||
|
||||
def test_save_array(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
filename = os.path.join(self.test_dir, "test_save_array.pos")
|
||||
self.pop.save_array(filename, self.pop.pos)
|
||||
|
||||
def test_load_array(self):
|
||||
n = 3
|
||||
filename = os.path.join(self.test_dir, "test_load_array")
|
||||
self.pop.setup(self.size, self.domain)
|
||||
|
||||
# expected array
|
||||
dt_exp = self.pop.get_pop_dtype(self.domain.start)
|
||||
a_exp = np.zeros((n,), dtype=dt_exp)
|
||||
a_exp['A'] = np.linspace(0, 1, n)
|
||||
a_exp['B'] = np.linspace(1, 2, n)
|
||||
a_exp['C'] = np.linspace(3, 4, n)
|
||||
a_exp['_rfac'] = np.linspace(5, 6, n)
|
||||
a_exp['_gen'] = np.array([3, 4, 7])
|
||||
a_exp['_particle'] = np.array([1, 0, 2])
|
||||
a_exp['_model'] = np.array([3, 6, 1])
|
||||
|
||||
# test array is a expected array with different column order
|
||||
dt_test = [('A', 'f4'), ('_particle', 'i4'), ('_rfac', 'f4'), ('C', 'f4'), ('_gen', 'i4'), ('B', 'f4'),
|
||||
('_model', 'i4')]
|
||||
names_test = [a[0] for a in dt_test]
|
||||
a_test = np.zeros((n,), dtype=dt_test)
|
||||
for name in names_test:
|
||||
a_test[name] = a_exp[name]
|
||||
header = " ".join(names_test)
|
||||
np.savetxt(filename, a_test, fmt='%g', header=header)
|
||||
|
||||
result = np.zeros((n,), dtype=dt_exp)
|
||||
result = self.pop.load_array(filename, result)
|
||||
self.assert_pop_array_equal(result, a_exp)
|
||||
|
||||
def test_constrain_position(self):
|
||||
# upper
|
||||
pos1 = 11.0
|
||||
vel1 = 5.0
|
||||
min1 = 0.0
|
||||
max1 = 10.0
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 're-enter')
|
||||
self.assertAlmostEqual(pos2, 1.0)
|
||||
self.assertAlmostEqual(vel2, vel1)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'bounce')
|
||||
self.assertAlmostEqual(pos2, 9.0)
|
||||
self.assertAlmostEqual(vel2, -vel1)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'scatter')
|
||||
self.assertGreaterEqual(pos2, 6.0)
|
||||
self.assertLessEqual(pos2, 10.0)
|
||||
self.assertGreaterEqual(vel2, 0.0)
|
||||
self.assertLessEqual(vel2, vel1)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'stick')
|
||||
self.assertAlmostEqual(pos2, max1)
|
||||
self.assertAlmostEqual(vel2, max1 - (pos1 - vel1))
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'random')
|
||||
self.assertGreaterEqual(pos2, 0.0)
|
||||
self.assertLessEqual(pos2, 10.0)
|
||||
self.assertGreaterEqual(vel2, -(max1 - min1))
|
||||
self.assertLessEqual(vel2, (max1 - min1))
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'expand')
|
||||
self.assertAlmostEqual(pos2, pos1)
|
||||
self.assertAlmostEqual(vel2, vel1)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max2, pos1)
|
||||
self.assertRaises(ValueError, population.Population.constrain_position, pos1, vel1, min1, max1, 'error')
|
||||
|
||||
# lower
|
||||
pos1 = -1.0
|
||||
vel1 = -5.0
|
||||
min1 = 0.0
|
||||
max1 = 10.0
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 're-enter')
|
||||
self.assertAlmostEqual(pos2, 9.0)
|
||||
self.assertAlmostEqual(vel2, vel1)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'bounce')
|
||||
self.assertAlmostEqual(pos2, 1.0)
|
||||
self.assertAlmostEqual(vel2, -vel1)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'scatter')
|
||||
self.assertGreaterEqual(pos2, 0.0)
|
||||
self.assertLessEqual(pos2, 4.0)
|
||||
self.assertGreaterEqual(vel2, vel1)
|
||||
self.assertLessEqual(vel2, 0.0)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'stick')
|
||||
self.assertAlmostEqual(pos2, min1)
|
||||
self.assertAlmostEqual(vel2, min1 - (pos1 - vel1))
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'random')
|
||||
self.assertGreaterEqual(pos2, 0.0)
|
||||
self.assertLessEqual(pos2, 10.0)
|
||||
self.assertGreaterEqual(vel2, -(max1 - min1))
|
||||
self.assertLessEqual(vel2, max1 - min1)
|
||||
self.assertAlmostEqual(min1, min2)
|
||||
self.assertAlmostEqual(max1, max2)
|
||||
pos2, vel2, min2, max2 = population.Population.constrain_position(pos1, vel1, min1, max1, 'expand')
|
||||
self.assertAlmostEqual(pos2, pos1)
|
||||
self.assertAlmostEqual(vel2, vel1)
|
||||
self.assertAlmostEqual(min2, pos1)
|
||||
self.assertAlmostEqual(max2, max1)
|
||||
self.assertRaises(ValueError, population.Population.constrain_position, pos1, vel1, min1, max1, 'error')
|
||||
|
||||
def test_patch_from_file(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
data_file = os.path.join(data_dir, "test_swarm.setup_with_results.1.dat")
|
||||
patch_size = 4
|
||||
expected_pos = {'A': [1.1, 1.2, 1.3, 1.4], 'B': [2.1, 2.2, 2.3, 2.4], 'C': [3.1, 3.2, 4.3, 3.4]}
|
||||
self.pop.patch_from_file(data_file)
|
||||
self.assertIsInstance(self.pop.pos_patch, np.ndarray)
|
||||
self.assertEqual(self.pop.pos_patch.shape, (patch_size,))
|
||||
np.testing.assert_array_equal(self.pop.pos_patch['_particle'], [1, 2, 3, 4])
|
||||
np.testing.assert_array_equal(self.pop.pos_patch['_gen'], [1, 2, 3, 4])
|
||||
np.testing.assert_array_almost_equal(self.pop.pos_patch['A'], expected_pos['A'])
|
||||
np.testing.assert_array_almost_equal(self.pop.pos_patch['B'], expected_pos['B'])
|
||||
np.testing.assert_array_almost_equal(self.pop.pos_patch['C'], expected_pos['C'])
|
||||
|
||||
def test_apply_patch(self):
|
||||
self.pop.setup(self.size, self.domain)
|
||||
expected_pos = self.pop.pos.copy()
|
||||
dt_test = [('A', 'f4'), ('_particle', 'i4'), ('_rfac', 'f4'), ('C', 'f4'), ('_model', 'i4')]
|
||||
patch_size = 3
|
||||
self.pop.pos_patch = np.zeros(patch_size, dtype=dt_test)
|
||||
self.pop.pos_patch['_particle'] = np.array([1, 2, 3])
|
||||
self.pop.pos_patch['_rfac'] = np.random.random_sample(patch_size)
|
||||
self.pop.pos_patch['_model'] = np.arange(patch_size)
|
||||
self.pop.pos_patch['A'] = np.array([1.1, 2.2, 3.3])
|
||||
self.pop.pos_patch['C'] = np.array([1.1, 2.2, 3.3])
|
||||
|
||||
expected_pos['A'][1] = 1.1
|
||||
expected_pos['C'][3] = 3.3
|
||||
expected_pos['_particle'] = np.arange(POP_SIZE)
|
||||
expected_pos['_gen'] = 0
|
||||
expected_pos['_model'] = np.arange(POP_SIZE)
|
||||
expected_pos['_rfac'] = 2.1
|
||||
|
||||
self.pop._apply_patch()
|
||||
self.assertIsNone(self.pop.pos_patch)
|
||||
self.assertEqual(self.pop.generation, 0)
|
||||
self.assertEqual(self.pop.model_count, POP_SIZE)
|
||||
self.assert_pop_array_equal(self.pop.pos, expected_pos)
|
||||
|
||||
def test_find_result(self):
|
||||
self.domain.min['A'] = -0.1
|
||||
self.domain.max['A'] = 0.1
|
||||
self.domain.min['B'] = 0.0
|
||||
self.domain.max['B'] = 1000.
|
||||
self.domain.min['C'] = 9.
|
||||
self.domain.max['C'] = 9.001
|
||||
self.size = 100
|
||||
self.pop.setup(self.size, self.domain)
|
||||
self.pop.results = self.pop.pos.copy()
|
||||
|
||||
expected_index = 77
|
||||
names = ['A', 'B', 'C']
|
||||
target0 = {key: self.pop.results[key][expected_index] for key in names}
|
||||
target1 = self.pop.results[names].copy()
|
||||
target1 = target1[expected_index]
|
||||
target2 = {key: target0[key] for key in ['C', 'B']}
|
||||
target3 = target2.copy()
|
||||
target3['C'] += 9.e-6
|
||||
target4 = {'A': random.random(), 'B': random.random(), 'C': 9.002}
|
||||
|
||||
result0 = self.pop.find_model(target0)
|
||||
self.assertEqual(result0, expected_index)
|
||||
result1 = self.pop.find_model(target1)
|
||||
self.assertEqual(result1, expected_index)
|
||||
result2 = self.pop.find_model(target2)
|
||||
self.assertEqual(result2, expected_index)
|
||||
result3 = self.pop.find_model(target3)
|
||||
self.assertEqual(result3, expected_index)
|
||||
self.assertRaises(ValueError, self.pop.find_model, target4)
|
||||
|
||||
def test_import_positions(self):
|
||||
"""
|
||||
test the population.Population.import_positions method.
|
||||
check the different type conversions.
|
||||
the main work is in test_import_positions_array.
|
||||
"""
|
||||
self.pop.setup(self.size, self.domain)
|
||||
|
||||
source_type = [('A', 'f4'), ('B', 'f4'), ('C', 'f4'), ('D', 'f4'),
|
||||
('_model', 'i4'), ('_particle', 'i4'), ('_gen', 'i4'), ('_rfac', 'f4')]
|
||||
source = np.array([(1.5, 3.5, 3.5, 4.5, 51, 52, 53, 0.5),
|
||||
(1.6, 2.6, 2.6, 4.6, 61, 62, 63, 0.6),
|
||||
(1.7, 2.7, 3.7, 4.7, 71, 72, 73, 0.7),
|
||||
(1.8, 2.8, 3.8, 4.8, 81, 82, 83, 0.8)], dtype=source_type)
|
||||
expected_type = [('_gen', 'i8'), ('_model', 'i8'), ('_particle', 'i8'), ('_rfac', 'f8'),
|
||||
('A', 'f8'), ('B', 'f8'), ('C', 'f8')]
|
||||
expected = np.array([(0, 0, 0, 0.0, 1.5, 3.5, 3.5),
|
||||
(0, 0, 0, 0.0, 1.6, 2.6, 2.6),
|
||||
(0, 0, 0, 0.0, 1.7, 2.7, 3.7),
|
||||
(0, 0, 0, 0.0, 1.8, 2.8, 3.8)], dtype=expected_type)
|
||||
expected_single = np.array([expected[0]], dtype=expected_type)
|
||||
|
||||
# None
|
||||
self.pop.clear_import()
|
||||
source_none = None
|
||||
retval = self.pop.import_positions(source_none)
|
||||
self.assertEqual(retval, 0)
|
||||
|
||||
# np.ndarray
|
||||
self.pop.clear_import()
|
||||
source_ndarray = source
|
||||
retval = self.pop.import_positions(source_ndarray)
|
||||
self.assertEqual(retval, expected.shape[0])
|
||||
self.assert_pop_array_equal(self.pop.pos_import, expected, msg="numpy.ndarray")
|
||||
|
||||
# np.void
|
||||
self.pop.clear_import()
|
||||
source_void = source[0]
|
||||
retval = self.pop.import_positions(source_void)
|
||||
self.assertEqual(retval, 1)
|
||||
self.assert_pop_array_equal(self.pop.pos_import, expected_single, msg="numpy.void")
|
||||
|
||||
# dict
|
||||
self.pop.clear_import()
|
||||
source_dict = {k: source[0][k] for k in source.dtype.names}
|
||||
retval = self.pop.import_positions(source_dict)
|
||||
self.assertEqual(retval, 1)
|
||||
self.assert_pop_array_equal(self.pop.pos_import, expected_single, msg="dict")
|
||||
|
||||
# sequence
|
||||
self.pop.clear_import()
|
||||
source_sequence = [row for row in source]
|
||||
retval = self.pop.import_positions(source_sequence)
|
||||
self.assertEqual(retval, expected.shape[0])
|
||||
self.assert_pop_array_equal(self.pop.pos_import, expected, msg="sequence")
|
||||
|
||||
# file
|
||||
filename = os.path.join(self.test_dir, "test_import_positions")
|
||||
self.pop.save_array(filename, source)
|
||||
self.pop.clear_import()
|
||||
retval = self.pop.import_positions(filename)
|
||||
self.assertEqual(retval, expected.shape[0])
|
||||
self.assert_pop_array_equal(self.pop.pos_import, expected, msg="file")
|
||||
|
||||
# callable
|
||||
def source_callable():
|
||||
return expected.copy()
|
||||
|
||||
self.pop.clear_import()
|
||||
retval = self.pop.import_positions(source_callable)
|
||||
self.assertEqual(retval, expected.shape[0])
|
||||
self.assert_pop_array_equal(self.pop.pos_import, expected, msg="callable")
|
||||
|
||||
def test_import_positions_array(self):
|
||||
"""
|
||||
test the population.Population.import_positions_array method.
|
||||
- import a data array, check type and size.
|
||||
- add to previous import.
|
||||
- ignore control fields.
|
||||
- no range or duplicate checking.
|
||||
- missing parameter.
|
||||
"""
|
||||
self.pop.setup(self.size, self.domain)
|
||||
source_type = [('A', 'f4'), ('B', 'f4'), ('C', 'f4'), ('D', 'f4'),
|
||||
('_model', 'i4'), ('_particle', 'i4'), ('_gen', 'i4'), ('_rfac', 'f4')]
|
||||
source = np.array([(1.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0),
|
||||
(1.5, 3.5, 3.5, 4.5, 51, 52, 53, 0.5),
|
||||
(1.6, 2.6, 2.6, 4.6, 61, 62, 63, 0.6),
|
||||
(1.7, 2.7, 3.7, 4.7, 71, 72, 73, 0.7),
|
||||
(1.8, 2.8, 3.8, 4.8, 81, 82, 83, 0.8)], dtype=source_type)
|
||||
self.pop.pos_import.resize(1)
|
||||
self.pop.pos_import[0]['A'] = 1.0
|
||||
expected_type = [('_gen', 'i8'), ('_model', 'i8'), ('_particle', 'i8'), ('_rfac', 'f8'),
|
||||
('A', 'f8'), ('B', 'f8'), ('C', 'f8')]
|
||||
expected = np.array([(0, 0, 0, 0.0, 1.0, 0.0, 0.0),
|
||||
(0, 0, 0, 0.0, 1.0, 0.0, 0.0),
|
||||
(0, 0, 0, 0.0, 1.5, 3.5, 3.5),
|
||||
(0, 0, 0, 0.0, 1.6, 2.6, 2.6),
|
||||
(0, 0, 0, 0.0, 1.7, 2.7, 3.7),
|
||||
(0, 0, 0, 0.0, 1.8, 2.8, 3.8)], dtype=expected_type)
|
||||
retval = self.pop.import_positions_array(source)
|
||||
self.assertEqual(retval, source.shape[0])
|
||||
self.assertEqual(self.pop.pos_import.dtype.names, self.pop.pos.dtype.names)
|
||||
self.assert_pop_array_equal(self.pop.pos_import, expected, msg="imported array")
|
||||
|
||||
source_type = [('B', 'f4'), ('C', 'f4'), ('D', 'f4'), ('E', 'f4'),
|
||||
('_model', 'i4'), ('_particle', 'i4'), ('_gen', 'i4'), ('_rfac', 'f4')]
|
||||
source = np.array([(1.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0),
|
||||
(1.8, 2.8, 3.8, 4.8, 81, 82, 83, 0.8)], dtype=source_type)
|
||||
self.assertRaises(ValueError, self.pop.import_positions_array, source)
|
||||
|
||||
def test_advance_from_import(self):
|
||||
"""
|
||||
test the population.Population.advance_from_import method.
|
||||
- array type and size.
|
||||
- range checks.
|
||||
- de-duplication.
|
||||
"""
|
||||
self.pop.setup(self.size, self.domain)
|
||||
self.pop.position_constrain_mode = 'error'
|
||||
source_type = [('A', 'f8'), ('B', 'f8'), ('C', 'f8'),
|
||||
('_model', 'i8'), ('_particle', 'i8'), ('_gen', 'i8'), ('_rfac', 'f8')]
|
||||
source = np.array([(1.3, 2.3, 3.3, 0, 0, 0, 0.0),
|
||||
(1.3, 2.3, 3.3, 0, 0, 0, 0.0),
|
||||
(1.4, 2.4, 3.4, 0, 0, 0, 0.0),
|
||||
(1.5, 3.5, 3.5, 0, 0, 0, 0.0),
|
||||
(1.6, 2.6, 2.6, 0, 0, 0, 0.0),
|
||||
(1.7, 2.7, 3.7, 0, 0, 0, 0.0),
|
||||
(1.8, 2.8, 3.8, 0, 0, 0, 0.0)], dtype=source_type)
|
||||
source = self.reorder_pop_array(source)
|
||||
results = np.array([(1.4, 2.4, 3.4, 0, 0, 0, 0.4)], dtype=source_type)
|
||||
results = self.reorder_pop_array(results)
|
||||
expected = np.array([(1.3, 2.3, 3.3, POP_SIZE + 0, 0, 0, 2.1),
|
||||
(1.7, 2.7, 3.7, POP_SIZE + 1, 1, 0, 2.1),
|
||||
(1.8, 2.8, 3.8, POP_SIZE + 2, 2, 0, 2.1)], dtype=source_type)
|
||||
expected = self.reorder_pop_array(expected)
|
||||
|
||||
self.pop.pos_import = source
|
||||
self.pop.results = results
|
||||
retval = self.pop.advance_from_import()
|
||||
self.assertEqual(retval, expected.shape[0])
|
||||
self.assertEqual(self.pop.size_act, expected.shape[0])
|
||||
pos_act = self.pop.pos[0:self.pop.size_act]
|
||||
self.assert_pop_array_equal(pos_act, expected)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user