예제 #1
0
 def test_linear_solve_matrix_tape(self):
     y = CenteredGrid(1, extrapolation.ZERO, x=3) * (1, 2)
     x0 = CenteredGrid(0, extrapolation.ZERO, x=3)
     for method in ['CG', 'CG-adaptive', 'auto']:
         solve = math.Solve(method, 0, 1e-3, x0=x0, max_iterations=100)
         with math.SolveTape() as solves:
             x = field.solve_linear(math.jit_compile_linear(field.laplace),
                                    y, solve)
         math.assert_close(x.values, [[-1.5, -2, -1.5], [-3, -4, -3]],
                           abs_tolerance=1e-3)
         assert len(solves) == 1
         assert solves[0] == solves[solve]
         math.assert_close(solves[solve].residual.values,
                           0,
                           abs_tolerance=1e-3)
         assert math.close(solves[solve].iterations, 2) or math.close(
             solves[solve].iterations, -1)
         with math.SolveTape(record_trajectories=True) as solves:
             x = field.solve_linear(math.jit_compile_linear(field.laplace),
                                    y, solve)
         math.assert_close(x.values, [[-1.5, -2, -1.5], [-3, -4, -3]],
                           abs_tolerance=1e-3)
         assert solves[solve].x.trajectory.size == 3
         math.assert_close(solves[solve].residual.trajectory[-1].values,
                           0,
                           abs_tolerance=1e-3)
예제 #2
0
def plot_solves():
    """
    While `plot_solves()` is active, certain performance optimizations and algorithm implementations may be disabled.
    """
    from . import math
    import pylab
    cycle = pylab.rcParams['axes.prop_cycle'].by_key()['color']
    with math.SolveTape(record_trajectories=True) as solves:
        try:
            yield solves
        finally:
            for i, result in enumerate(solves):
                assert isinstance(result, math.SolveInfo)
                from phi.math._tensors import disassemble_tree
                _, (residual, ) = disassemble_tree(result.residual)
                residual_mse = math.mean(math.sqrt(math.sum(residual**2)),
                                         residual.shape.without('trajectory'))
                residual_mse_max = math.max(
                    math.sqrt(math.sum(residual**2)),
                    residual.shape.without('trajectory'))
                # residual_mean = math.mean(math.abs(residual), residual.shape.without('trajectory'))
                residual_max = math.max(math.abs(residual),
                                        residual.shape.without('trajectory'))
                pylab.plot(residual_mse.numpy(),
                           label=f"{i}: {result.method}",
                           color=cycle[i % len(cycle)])
                pylab.plot(residual_max.numpy(),
                           '--',
                           alpha=0.2,
                           color=cycle[i % len(cycle)])
                pylab.plot(residual_mse_max.numpy(),
                           alpha=0.2,
                           color=cycle[i % len(cycle)])
                print(
                    f"Solve {i}: {result.method} ({1000 * result.solve_time:.1f} ms)\n"
                    f"\t{result.solve}\n"
                    f"\t{result.msg}\n"
                    f"\tConverged: {result.converged}\n"
                    f"\tDiverged: {result.diverged}\n"
                    f"\tIterations: {result.iterations}\n"
                    f"\tFunction evaulations: {result.function_evaluations.trajectory[-1]}"
                )
            pylab.yscale('log')
            pylab.ylabel("Residual: MSE / max / individual max")
            pylab.xlabel("Iteration")
            pylab.title(f"Solve Convergence")
            pylab.legend(loc='upper right')
            pylab.savefig(f"pressure-solvers-FP32.png")
            pylab.show()
예제 #3
0
 def test_solve_diverge(self):
     y = math.ones(spatial(x=2)) * (1, 2)
     x0 = math.zeros(spatial(x=2))
     for method in ['CG']:
         solve = Solve(method, 0, 1e-3, x0=x0, max_iterations=100)
         try:
             field.solve_linear(math.jit_compile_linear(math.laplace), y,
                                solve)
             assert False
         except Diverged:
             pass
         with math.SolveTape(record_trajectories=True) as solves:
             try:
                 field.solve_linear(math.jit_compile_linear(math.laplace),
                                    y, solve)  # impossible
                 assert False
             except Diverged:
                 pass
예제 #4
0
 def test_solve_linear_function_batched(self):
     y = CenteredGrid(1, extrapolation.ZERO, x=3) * (1, 2)
     x0 = CenteredGrid(0, extrapolation.ZERO, x=3)
     for method in ['CG', 'CG-adaptive', 'auto']:
         solve = math.Solve(method, 0, 1e-3, x0=x0, max_iterations=100)
         x = field.solve_linear(math.jit_compile_linear(field.laplace), y,
                                solve)
         math.assert_close(x.values,
                           math.wrap([[-1.5, -2, -1.5], [-3, -4, -3]],
                                     channel('vector'), spatial('x')),
                           abs_tolerance=1e-3)
         with math.SolveTape() as solves:
             x = field.solve_linear(math.jit_compile_linear(field.laplace),
                                    y, solve)
         math.assert_close(x.values,
                           math.wrap([[-1.5, -2, -1.5], [-3, -4, -3]],
                                     channel('vector'), spatial('x')),
                           abs_tolerance=1e-3)
         assert len(solves) == 1
         assert solves[0] == solves[solve]
         math.assert_close(solves[solve].residual.values,
                           0,
                           abs_tolerance=1e-3)
예제 #5
0
    def test_minimize(self):
        def loss(x, y):
            return math.l2_loss(x - 1) + math.l2_loss(y + 1)

        for backend in BACKENDS:
            if backend.supports(Backend.functional_gradient):
                with backend:
                    x0 = tensor([0, 0, 0], spatial('x')), tensor([-1, -1, -1],
                                                                 spatial('y'))
                    x, y = math.minimize(
                        loss, math.Solve('L-BFGS-B', 0, 1e-3, x0=x0))
                    math.assert_close(x,
                                      1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)
                    math.assert_close(y,
                                      -1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)

                    x0 = tensor([[0, 0, 0], [1, 1, 1]], batch('batch'),
                                spatial('x')), tensor(
                                    [[0, 0, 0], [-1, -1, -1]], batch('batch'),
                                    spatial('y'))
                    x, y = math.minimize(
                        loss, math.Solve('L-BFGS-B', 0, 1e-3, x0=x0))
                    math.assert_close(x,
                                      1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)
                    math.assert_close(y,
                                      -1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)

                    with math.SolveTape() as solves:
                        x, y = math.minimize(
                            loss, math.Solve('L-BFGS-B', 0, 1e-3, x0=x0))
                    math.assert_close(x,
                                      1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)
                    math.assert_close(y,
                                      -1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)
                    math.assert_close(solves[0].residual,
                                      0,
                                      abs_tolerance=1e-4)
                    assert (solves[0].iterations <= (4, 0)).all
                    assert (solves[0].function_evaluations <= (30, 1)).all

                    with math.SolveTape(
                            record_trajectories=True) as trajectories:
                        x, y = math.minimize(
                            loss, math.Solve('L-BFGS-B', 0, 1e-3, x0=x0))
                    math.assert_close(x,
                                      1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)
                    math.assert_close(y,
                                      -1,
                                      abs_tolerance=1e-3,
                                      msg=backend.name)
                    math.assert_close(trajectories[0].residual.trajectory[-1],
                                      0,
                                      abs_tolerance=1e-4)
                    assert (
                        trajectories[0].iterations == solves[0].iterations).all
                    assert trajectories[
                        0].residual.trajectory.size == trajectories[0].x[
                            0].trajectory.size
                    assert trajectories[0].residual.trajectory.size > 1