def test_analytic():
    nb_pts = 1488
    s = 4 * np.pi
    x = np.arange(nb_pts) * s / nb_pts
    h = np.sin(x)
    t1 = UniformLineScan(h, (s, ))
    t2 = UniformLineScan(h, (s, ), periodic=True)
    t3 = t1.to_nonuniform()

    d1 = t1.derivative(1)
    d2 = t2.derivative(1)
    d3 = t3.derivative(1)

    np.testing.assert_allclose(d1,
                               np.cos(x[:-1] + (x[1] - x[0]) / 2),
                               atol=1e-5)
    np.testing.assert_allclose(d2, np.cos(x + (x[1] - x[0]) / 2), atol=1e-5)
    np.testing.assert_allclose(d3,
                               np.cos(x[:-1] + (x[1] - x[0]) / 2),
                               atol=1e-5)

    d1 = t1.derivative(2)
    d2 = t2.derivative(2)
    d3 = t3.derivative(2)

    np.testing.assert_allclose(d1, -np.sin(x[:-2] + (x[1] - x[0])), atol=1e-5)
    np.testing.assert_allclose(d2, -np.sin(x), atol=1e-5)
    np.testing.assert_allclose(d3, -np.sin(x[:-2] + (x[1] - x[0])), atol=1e-5)
def test_scale_factor():
    nx = 8
    sx = 1

    topography = fourier_synthesis((nx, ), (sx, ),
                                   0.8,
                                   rms_height=1.,
                                   periodic=True)
    topography1 = UniformLineScan(topography.heights()[::2], sx, periodic=True)
    topography2 = UniformLineScan(topography.heights()[1::2],
                                  sx,
                                  periodic=True)

    d1 = topography.derivative(1, scale_factor=1)
    d2 = topography.derivative(1, scale_factor=np.uint32(2))
    d3 = topography1.derivative(1, scale_factor=1)
    d4 = topography2.derivative(1, scale_factor=1)

    assert len(d2) == len(d1)
    np.testing.assert_allclose(d3, d2[::2])
    np.testing.assert_allclose(d4, d2[1::2])

    topography = fourier_synthesis((nx, ), (sx, ),
                                   0.8,
                                   rms_height=1.,
                                   periodic=False)
    topography1 = UniformLineScan(topography.heights()[::2],
                                  sx,
                                  periodic=False)
    topography2 = UniformLineScan(topography.heights()[1::2],
                                  sx,
                                  periodic=False)

    d1, d2 = topography.derivative(1, scale_factor=[1, 2])
    d3 = topography1.derivative(1, scale_factor=1)
    d4 = topography2.derivative(1, scale_factor=1)

    assert len(d2) == len(d1) - 1
    np.testing.assert_allclose(d3, d2[::2])
    np.testing.assert_allclose(d4, d2[1::2])

    ny = 10
    sy = 0.8
    topography = fourier_synthesis((nx, ny), (sx, sy),
                                   0.8,
                                   rms_height=1.,
                                   periodic=False)

    dx, dy = topography.derivative(1, scale_factor=[1, 2, 4])
    dx1, dx2, dx4 = dx
    dy1, dy2, dy4 = dy

    assert dx1.shape[0] == nx - 1
    assert dx1.shape[1] == ny - 1
    assert dy1.shape[0] == nx - 1
    assert dy1.shape[1] == ny - 1
    assert dx2.shape[0] == nx - 2
    assert dx2.shape[1] == ny - 2
    assert dy2.shape[0] == nx - 2
    assert dy2.shape[1] == ny - 2
    assert dx4.shape[0] == nx - 4
    assert dx4.shape[1] == ny - 4
    assert dy4.shape[0] == nx - 4
    assert dy4.shape[1] == ny - 4

    dx, dy = topography.derivative(1, scale_factor=[(1, 4), (2, 1), (4, 2)])
    dxn1, dxn2, dxn4 = dx
    dyn4, dyn1, dyn2 = dy
    np.testing.assert_allclose(dxn1, dx1)
    np.testing.assert_allclose(dyn1, dy1)
    np.testing.assert_allclose(dxn2, dx2)
    np.testing.assert_allclose(dyn2, dy2)
    np.testing.assert_allclose(dxn4, dx4)
    np.testing.assert_allclose(dyn4, dy4)