Ejemplo n.º 1
0
def test_batch_generator():
    size = 10
    batch_size = 3
    x = np.arange(size, dtype=np.float32)
    answer_x = np.arange(batch_size) % size
    generator = PredefinedGenerator(x)
    batch_generator = BatchGenerator(generator, batch_size)
    for _ in range(50):
        x = batch_generator.get_examples()
        assert _check_shape_and_grad(batch_generator, batch_size, x)
        assert _check_iterable_equal(answer_x, x)
        assert len(batch_generator.cached_xs) <= size + max(size, batch_size)
        # update answer for next iteration
        answer_x = (answer_x + batch_size) % size

    size = 3
    batch_size = 10
    x = np.arange(size, dtype=np.float32)
    y = np.arange(size, dtype=np.float32)
    answer_x = np.arange(batch_size) % size
    answer_y = np.arange(batch_size) % size
    generator = PredefinedGenerator(x, y)
    batch_generator = BatchGenerator(generator, batch_size)
    for _ in range(50):
        x, y = batch_generator.get_examples()
        assert _check_shape_and_grad(batch_generator, batch_size, x, y)
        assert _check_iterable_equal(answer_x, x)
        assert _check_iterable_equal(answer_y, y)
        assert len(batch_generator.cached_xs) <= size + max(size, batch_size)
        # update answer for next iteration
        answer_x = (answer_x + batch_size) % size
        answer_y = (answer_y + batch_size) % size

    str(batch_generator)
    repr(batch_generator)
Ejemplo n.º 2
0
def test_ensemble_generator():
    size = 100

    generator1 = Generator1D(size)
    ensemble_generator = EnsembleGenerator(generator1)
    x = ensemble_generator.get_examples()
    assert _check_shape_and_grad(ensemble_generator, size, x)

    old_x = torch.rand(size)
    old_y = torch.rand(size)
    old_z = torch.rand(size)
    generator1 = PredefinedGenerator(old_x)
    generator2 = PredefinedGenerator(old_y)
    generator3 = PredefinedGenerator(old_z)
    ensemble_generator = EnsembleGenerator(generator1, generator2, generator3)
    x, y, z = ensemble_generator.get_examples()
    assert _check_shape_and_grad(ensemble_generator, size, x, y, z)
    assert _check_iterable_equal(old_x, x)
    assert _check_iterable_equal(old_y, y)
    assert _check_iterable_equal(old_z, z)

    old_x = torch.rand(size)
    old_y = torch.rand(size)
    generator1 = PredefinedGenerator(old_x)
    generator2 = PredefinedGenerator(old_y)
    product_generator = generator1 * generator2
    x, y = product_generator.get_examples()
    assert _check_shape_and_grad(product_generator, size, x, y)
    assert _check_iterable_equal(old_x, x)
    assert _check_iterable_equal(old_y, y)

    str(ensemble_generator)
    repr(ensemble_generator)
Ejemplo n.º 3
0
def test_transform_generator():
    size = 100
    x = np.arange(0, size, dtype=np.float32)
    x_expected = np.sin(x)
    generator = PredefinedGenerator(x)
    transform_generator = TransformGenerator(generator, [torch.sin])
    x = transform_generator.get_examples()
    assert _check_shape_and_grad(transform_generator, size, x)
    assert _check_iterable_equal(x, x_expected)

    x = np.arange(0, size, dtype=np.float32)
    y = np.arange(0, size, dtype=np.float32)
    z = np.arange(0, size, dtype=np.float32)
    x_expected = np.sin(x)
    y_expected = y
    z_expected = -z
    generator = PredefinedGenerator(x, y, z)
    transform_generator = TransformGenerator(generator,
                                             [torch.sin, None, lambda a: -a])
    x, y, z = transform_generator.get_examples()
    assert _check_shape_and_grad(transform_generator, size, x, y, z)
    assert _check_iterable_equal(x, x_expected)
    assert _check_iterable_equal(y, y_expected)
    assert _check_iterable_equal(z, z_expected)

    transform_generator = TransformGenerator(generator,
                                             transform=lambda x, y, z:
                                             (torch.sin(x), y, -z))
    x, y, z = transform_generator.get_examples()
    assert _check_shape_and_grad(transform_generator, size, x, y, z)
    assert _check_iterable_equal(x, x_expected)
    assert _check_iterable_equal(y, y_expected)
    assert _check_iterable_equal(z, z_expected)

    print('testing generator name: ', transform_generator)
Ejemplo n.º 4
0
def test_predefined_generator():
    size = 100

    old_x = torch.arange(size, dtype=torch.float, requires_grad=False)
    predefined_generator = PredefinedGenerator(old_x)
    x = predefined_generator.get_examples()
    assert _check_shape_and_grad(predefined_generator, size, x)
    assert _check_iterable_equal(old_x, x)

    old_x = torch.arange(size, dtype=torch.float, requires_grad=False)
    old_y = torch.arange(size, dtype=torch.float, requires_grad=True)
    old_z = torch.arange(size, dtype=torch.float, requires_grad=False)
    predefined_generator = PredefinedGenerator(old_x, old_y, old_z)
    x, y, z = predefined_generator.get_examples()
    assert _check_shape_and_grad(predefined_generator, size, x, y, z)
    assert _check_iterable_equal(old_x, x)
    assert _check_iterable_equal(old_y, y)
    assert _check_iterable_equal(old_z, z)

    x_list = [i * 2.0 for i in range(size)]
    y_tuple = tuple([i * 3.0 for i in range(size)])
    z_array = np.array([i * 4.0 for i in range(size)]).reshape(-1, 1)
    w_tensor = torch.arange(size, dtype=torch.float)
    predefined_generator = PredefinedGenerator(x_list, y_tuple, z_array,
                                               w_tensor)
    x, y, z, w = predefined_generator.get_examples()
    assert _check_shape_and_grad(predefined_generator, size, x, y, z, w)
    assert _check_iterable_equal(x_list, x)
    assert _check_iterable_equal(y_tuple, y)
    assert _check_iterable_equal(z_array, z)
    assert _check_iterable_equal(w_tensor, w)

    str(predefined_generator)
    repr(predefined_generator)
Ejemplo n.º 5
0
def test_resample_generator():
    size = 100

    sample_size = size
    x_expected = np.arange(size, dtype=np.float32)
    generator = PredefinedGenerator(x_expected)
    resample_generator = ResampleGenerator(generator,
                                           size=sample_size,
                                           replacement=False)
    x = resample_generator.get_examples()
    assert _check_shape_and_grad(resample_generator, sample_size, x)
    # noinspection PyTypeChecker
    assert _check_iterable_equal(torch.sort(x)[0], x_expected)

    sample_size = size // 2
    x = np.arange(size, dtype=np.float32)
    y = np.arange(size, size * 2, dtype=np.float32)
    generator = PredefinedGenerator(x, y)
    resample_generator = ResampleGenerator(generator,
                                           size=sample_size,
                                           replacement=False)
    x, y = resample_generator.get_examples()
    assert _check_shape_and_grad(resample_generator, sample_size, x, y)
    assert _check_iterable_equal(x + 100, y)
    assert len(torch.unique(x.detach())) == len(x)

    sample_size = size * 3 // 4
    x = np.arange(size, dtype=np.float32)
    y = np.arange(size, size * 2, dtype=np.float32)
    generator = PredefinedGenerator(x, y)
    resample_generator = ResampleGenerator(generator,
                                           size=sample_size,
                                           replacement=True)
    x, y = resample_generator.get_examples()
    assert _check_shape_and_grad(resample_generator, sample_size, x, y)
    assert _check_iterable_equal(x + 100, y)
    assert len(torch.unique(x.detach())) < len(x)

    sample_size = size * 2
    x = np.arange(size, dtype=np.float32)
    y = np.arange(size, size * 2, dtype=np.float32)
    z = np.arange(size * 2, size * 3, dtype=np.float32)
    generator = PredefinedGenerator(x, y, z)
    resample_generator = ResampleGenerator(generator,
                                           size=sample_size,
                                           replacement=True)
    x, y, z = resample_generator.get_examples()
    assert _check_shape_and_grad(resample_generator, sample_size, x, y, z)
    assert _check_iterable_equal(x + 100, y)
    assert _check_iterable_equal(y + 100, z)
    assert len(torch.unique(x.detach())) < len(x)

    str(resample_generator)
    repr(resample_generator)
Ejemplo n.º 6
0
def test_filter_generator():
    grid = (10, 10)
    size = 100

    x = [i * 1.0 for i in range(size)]
    filter_fn = lambda a: (a[0] % 2 == 0)
    filter_fn_2 = lambda a: (a % 2 == 0)
    x_expected = filter(filter_fn_2, x)

    generator = PredefinedGenerator(x)
    filter_generator = FilterGenerator(generator,
                                       filter_fn=filter_fn,
                                       update_size=True)
    x = filter_generator.get_examples()
    assert _check_shape_and_grad(filter_generator, size // 2, x)
    assert _check_iterable_equal(x_expected, x)

    x = [i * 1.0 for i in range(size)]
    y = [-i * 1.0 for i in range(size)]
    filter_fn = lambda ab: (ab[0] % 2 == 0) & (ab[1] > -size / 2)
    x_expected, y_expected = list(zip(*filter(filter_fn, zip(x, y))))
    generator = PredefinedGenerator(x, y)
    filter_generator = FilterGenerator(generator, filter_fn)
    x, y = filter_generator.get_examples()
    assert _check_shape_and_grad(filter_generator, size // 4, x, y)
    assert _check_iterable_equal(x_expected, x)
    assert _check_iterable_equal(y_expected, y)

    generator = Generator2D(grid)
    filter_fn = lambda ab: (ab[0] > 0.5) & (ab[1] < 0.5)
    filter_generator = FilterGenerator(generator, filter_fn)
    for _ in range(5):
        x, y = filter_generator.get_examples()
        assert _check_shape_and_grad(filter_generator, None, x, y)

    fixed_size = 42
    filter_generator = FilterGenerator(generator,
                                       filter_fn,
                                       size=fixed_size,
                                       update_size=False)
    for _ in range(5):
        assert _check_shape_and_grad(filter_generator, fixed_size)
        filter_generator.get_examples()

    str(filter_generator)
    repr(filter_generator)
Ejemplo n.º 7
0
def test_arbitrary_boundary():
    def solution_analytical_problem_c(x, y):
        return np.log(1 + x**2 + y**2)

    def gradient_solution_analytical_problem_c(x, y):
        return 2 * x / (1 + x**2 + y**2), 2 * y / (1 + x**2 + y**2),

    # creating control points for Dirichlet boundary conditions

    edge_length = 2.0 / np.sin(np.pi / 3) / 4
    points_on_each_edge = 11
    step_size = edge_length / (points_on_each_edge - 1)

    direction_theta = np.pi * 2 / 3
    left_turn_theta = np.pi * 1 / 3
    right_turn_theta = -np.pi * 2 / 3

    dirichlet_control_points_problem_c = []
    point_x, point_y = 0.0, -1.0
    for i_edge in range(6):
        for i_step in range(points_on_each_edge - 1):
            dirichlet_control_points_problem_c.append(
                DirichletControlPoint(loc=(point_x, point_y),
                                      val=solution_analytical_problem_c(
                                          point_x, point_y)))
            point_x += step_size * np.cos(direction_theta)
            point_y += step_size * np.sin(direction_theta)
        direction_theta += left_turn_theta if (i_edge %
                                               2 == 0) else right_turn_theta

    # dummy control points to form closed domain

    radius_circle = 1.0 / np.sin(np.pi / 6)
    center_circle_x = radius_circle * np.cos(np.pi / 6)
    center_circle_y = 0.0

    dirichlet_control_points_problem_c_dummy = []
    for theta in np.linspace(-np.pi * 5 / 6, np.pi * 5 / 6, 60):
        point_x = center_circle_x + radius_circle * np.cos(theta)
        point_y = center_circle_y + radius_circle * np.sin(theta)
        dirichlet_control_points_problem_c_dummy.append(
            DirichletControlPoint(loc=(point_x, point_y),
                                  val=solution_analytical_problem_c(
                                      point_x, point_y)))

    # all Dirichlet control points

    dirichlet_control_points_problem_c_all = \
        dirichlet_control_points_problem_c + dirichlet_control_points_problem_c_dummy

    # creating control points for Neumann boundary condition

    edge_length = 2.0 / np.sin(np.pi / 3) / 4
    points_on_each_edge = 11
    step_size = edge_length / (points_on_each_edge - 1)

    normal_theta = np.pi / 6

    direction_theta = -np.pi * 1 / 3
    left_turn_theta = np.pi * 1 / 3
    right_turn_theta = -np.pi * 2 / 3

    neumann_control_points_problem_c = []
    point_x, point_y = 0.0, 1.0
    for i_edge in range(6):
        normal_x = np.cos(normal_theta)
        normal_y = np.sin(normal_theta)

        # skip the points on the "tip", their normal vector is undefined?
        point_x += step_size * np.cos(direction_theta)
        point_y += step_size * np.sin(direction_theta)

        for i_step in range(points_on_each_edge - 2):
            grad_x, grad_y = gradient_solution_analytical_problem_c(
                point_x, point_y)
            neumann_val = grad_x * normal_x + grad_y * normal_y
            neumann_control_points_problem_c.append(
                NeumannControlPoint(loc=(point_x, point_y),
                                    val=neumann_val,
                                    normal_vector=(normal_x, normal_y)))
            point_x += step_size * np.cos(direction_theta)
            point_y += step_size * np.sin(direction_theta)
        direction_theta += left_turn_theta if (i_edge %
                                               2 == 0) else right_turn_theta
        normal_theta += left_turn_theta if (i_edge %
                                            2 == 0) else right_turn_theta

    # dummy control points to form closed domain

    radius_circle = 1.0 / np.sin(np.pi / 6)
    center_circle_x = -radius_circle * np.cos(np.pi / 6)
    center_circle_y = 0.0

    neumann_control_points_problem_c_dummy = []
    for theta in np.linspace(np.pi * 1 / 6, np.pi * 11 / 6, 60):
        point_x = center_circle_x + radius_circle * np.cos(theta)
        point_y = center_circle_y + radius_circle * np.sin(theta)
        normal_x = np.cos(theta)
        normal_y = np.sin(theta)
        grad_x, grad_y = gradient_solution_analytical_problem_c(
            point_x, point_y)
        neumann_val = grad_x * normal_x + grad_y * normal_y
        neumann_control_points_problem_c_dummy.append(
            NeumannControlPoint(loc=(point_x, point_y),
                                val=neumann_val,
                                normal_vector=(normal_x, normal_y)))

    # all Neumann control points

    neumann_control_points_problem_c_all = \
        neumann_control_points_problem_c + neumann_control_points_problem_c_dummy

    cbc_problem_c = CustomBoundaryCondition(
        center_point=Point(loc=(0.0, 0.0)),
        dirichlet_control_points=dirichlet_control_points_problem_c_all,
        neumann_control_points=neumann_control_points_problem_c_all)

    def get_grid(x_from_to,
                 y_from_to,
                 x_n_points=100,
                 y_n_points=100,
                 as_tensor=False):
        x_from, x_to = x_from_to
        y_from, y_to = y_from_to
        if as_tensor:
            x = torch.linspace(x_from, x_to, x_n_points)
            y = torch.linspace(y_from, y_to, y_n_points)
            return torch.meshgrid(x, y)
        else:
            x = np.linspace(x_from, x_to, x_n_points)
            y = np.linspace(y_from, y_to, y_n_points)
            return np.meshgrid(x, y)

    def to_np(tensor):
        return tensor.detach().numpy()

    xx_train, yy_train = get_grid(x_from_to=(-1, 1),
                                  y_from_to=(-1, 1),
                                  x_n_points=28,
                                  y_n_points=28,
                                  as_tensor=True)
    is_in_domain_train = cbc_problem_c.in_domain(xx_train, yy_train)
    xx_train, yy_train = to_np(xx_train), to_np(yy_train)
    xx_train, yy_train = xx_train[is_in_domain_train], yy_train[
        is_in_domain_train]
    train_gen = PredefinedGenerator(xx_train, yy_train)

    xx_valid, yy_valid = get_grid(x_from_to=(-1, 1),
                                  y_from_to=(-1, 1),
                                  x_n_points=10,
                                  y_n_points=10,
                                  as_tensor=True)
    is_in_domain_valid = cbc_problem_c.in_domain(xx_valid, yy_valid)
    xx_valid, yy_valid = to_np(xx_valid), to_np(yy_valid)
    xx_valid, yy_valid = xx_valid[is_in_domain_valid], yy_valid[
        is_in_domain_valid]
    valid_gen = PredefinedGenerator(xx_valid, yy_valid)

    def rmse(u, x, y):
        true_u = torch.log(1 + x**2 + y**2)
        return torch.mean((u - true_u)**2)**0.5

    # nabla^2 psi(x, y) = (e^(-x))(x-2+y^3+6y)
    def de_problem_c(u, x, y):
        return diff(u, x, order=2) + diff(u, y, order=2) + torch.exp(
            u) - 1.0 - x**2 - y**2 - 4.0 / (1.0 + x**2 + y**2)**2

    # fully connected network with one hidden layer (100 hidden units with ELU activation)
    net = FCNN(n_input_units=2, hidden_units=(100, 100), actv=nn.ELU)
    adam = optim.Adam(params=net.parameters(), lr=0.001)

    # train on 28 X 28 grid
    solution_neural_net_problem_c, history_problem_c = solve2D(
        pde=de_problem_c,
        condition=cbc_problem_c,
        xy_min=(-1, -1),
        xy_max=(1, 1),
        train_generator=train_gen,
        valid_generator=valid_gen,
        net=net,
        max_epochs=1,
        batch_size=128,
        optimizer=adam,
        monitor=Monitor2D(check_every=1,
                          xy_min=(-1, -1),
                          xy_max=(1, 1),
                          valid_generator=valid_gen),
        metrics={'rmse': rmse})

    xs = torch.tensor([p.loc[0] for p in dirichlet_control_points_problem_c],
                      requires_grad=True).reshape(-1, 1)
    ys = torch.tensor([p.loc[1] for p in dirichlet_control_points_problem_c],
                      requires_grad=True).reshape(-1, 1)
    us = solution_neural_net_problem_c(xs, ys, as_type='np')
    true_us = solution_analytical_problem_c(to_np(xs), to_np(ys))
    assert isclose(us, true_us, atol=1e-4).all()

    xs = torch.tensor([p.loc[0] for p in neumann_control_points_problem_c],
                      requires_grad=True).reshape(-1, 1)
    ys = torch.tensor([p.loc[1] for p in neumann_control_points_problem_c],
                      requires_grad=True).reshape(-1, 1)
    us = solution_neural_net_problem_c(xs, ys)
    nxs = torch.tensor([
        p.normal_vector[0] for p in neumann_control_points_problem_c
    ]).reshape(-1, 1)
    nys = torch.tensor([
        p.normal_vector[1] for p in neumann_control_points_problem_c
    ]).reshape(-1, 1)
    normal_derivative = to_np(nxs * diff(us, xs) +
                              nys * diff(us, ys)).flatten()
    true_normal_derivative = np.array(
        [p.val for p in neumann_control_points_problem_c])
    assert isclose(normal_derivative, true_normal_derivative, atol=1e-2).all()