def test_squared_euclidean_cost(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C_XY = squared_euclidean_cost(X, Y) C = np.zeros_like(C_XY) for i in range(len(X)): for j in range(len(Y)): C[i, j] = 0.5 * np.sum((X[i] - Y[j])**2) assert_array_almost_equal(C_XY, C) C_XX = squared_euclidean_cost(X, X) C_YY = squared_euclidean_cost(Y, Y) C_XY2, C_XX2, C_YY2 = squared_euclidean_cost(X, Y, return_all=True) assert_array_almost_equal(C_XY, C_XY2) assert_array_almost_equal(C_XX, C_XX2) assert_array_almost_equal(C_YY, C_YY2)
def test_squared_euclidean_cost_log_vjp(self): def f(X, Y): C = squared_euclidean_cost(X, Y, log=True) return sdtw_C(C) X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y, log=True) val, grad_C = sdtw_value_and_grad_C(C) grad_X = squared_euclidean_cost_vjp(X, Y, grad_C, log=True) grad_num = _num_gradient(functools.partial(f, Y=Y), X) assert_array_almost_equal(grad_X, grad_num)
def test_squared_euclidean_cost_vjp(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) vjp = squared_euclidean_cost_vjp(X, Y, C) vjp2 = np.zeros_like(vjp) for i in range(len(X)): for j in range(len(Y)): for k in range(X.shape[1]): vjp2[i, k] += C[i, j] * (X[i, k] - Y[j, k]) assert_array_almost_equal(vjp, vjp2)
def test_sdtw(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) assert_almost_equal(sdtw_C(C), _sdtw_brute_force(C)) assert_almost_equal(sdtw_C(C), sdtw_value_and_grad_C(C)[0]) assert_almost_equal(sdtw_C(C), sdtw(X, Y)) assert_almost_equal(sdtw_C(C, gamma=0.1), _sdtw_brute_force(C, gamma=0.1)) assert_almost_equal(sdtw_C(C, gamma=0.1), sdtw_value_and_grad_C(C, gamma=0.1)[0])
def test_sharp_sdtw_grad(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) for gamma in (0.1, 1.0): G = sharp_sdtw_value_and_grad_C(C, gamma=gamma)[1] f = functools.partial(sharp_sdtw_C, gamma=gamma) G_num = _num_gradient(f, C) assert_array_almost_equal(G, G_num) G = sharp_sdtw_value_and_grad(X, Y, gamma=gamma)[1] f = functools.partial(sharp_sdtw, Y=Y, gamma=gamma) G_num = _num_gradient(f, X) assert_array_almost_equal(G, G_num)
def test_sdtw_entropy(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) gamma = 1.0 eps = 1e-6 p = _probas(C, gamma=gamma) H1 = -np.dot(p, np.log(p)) H2 = sdtw_entropy_C(C, gamma=gamma) H3 = -(sdtw_C(C, gamma + eps) - sdtw_C(C, gamma - eps)) / (2 * eps) H4 = sdtw_entropy(X, Y, gamma=gamma) assert_almost_equal(H1, H2) assert_almost_equal(H1, H3) assert_almost_equal(H1, H4)
def test_sharp_sdtw(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) for gamma in (0.1, 1.0): E = sdtw_value_and_grad_C(C, gamma=gamma)[1] val1 = np.vdot(E, C) val2 = sharp_sdtw_C(C, gamma=gamma) val3 = sharp_sdtw_value_and_grad_C(C, gamma=gamma)[0] val4 = sharp_sdtw_value_and_grad(X, Y, gamma=gamma)[0] val5 = sharp_sdtw(X, Y, gamma=gamma) assert_almost_equal(val1, val2) assert_almost_equal(val1, val3) assert_almost_equal(val1, val4) assert_almost_equal(val1, val5)
def test_mean_cost_grad(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) A_sum = np.zeros_like(C) n = 0 for A in alignment_matrices(*C.shape): A_sum += A n += 1 A_mean1 = A_sum / n A_mean2 = mean_cost_value_and_grad_C(C)[1] assert_array_almost_equal(A_mean1, A_mean2) G = _num_gradient(mean_cost_C, A_sum) # Any matrix can be used. assert_array_almost_equal(A_mean1, G)
def test_mean_cost(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) scores = [] for A in alignment_matrices(*C.shape): scores.append(np.vdot(A, C)) val1 = np.mean(scores) val2 = mean_cost_C(C) val3 = mean_cost_value_and_grad_C(C)[0] val4 = mean_cost(X, Y) val5 = mean_cost_value_and_grad(X, Y)[0] assert_almost_equal(val1, val2) assert_almost_equal(val1, val3) assert_almost_equal(val1, val4) assert_almost_equal(val1, val5)
def test_sdtw_grad_C(self): X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) V, P = sdtw_C(C, return_all=True) G = sdtw_grad_C(P) G_num = _num_gradient(sdtw_C, C) G_bf = _expectation_brute_force(C) assert_array_almost_equal(G, G_num) assert_array_almost_equal(G, G_bf) # Check value_and_grad. for gamma in (0.1, 1.0): G = sdtw_value_and_grad_C(C, gamma=gamma)[1] G_bf = _expectation_brute_force(C, gamma=gamma) assert_array_almost_equal(G, G_bf)
def test_sdtw_hessian_product(self): def f(C, M): V, P = sdtw_C(C, return_all=True) return sdtw_directional_derivative_C(P, M) X, Y = _make_time_series(size_X=3, size_Y=4, num_dim=2) C = squared_euclidean_cost(X, Y) V, P = sdtw_C(C, return_all=True) E = sdtw_grad_C(P, return_all=True) V_dot = sdtw_directional_derivative_C(P, C, return_all=True) hvp = sdtw_hessian_product_C(P, E, V_dot) hvp_num = _num_gradient(functools.partial(f, M=C), C) # The Hessian product is equal to the gradient of the directional derivative. assert_array_almost_equal(hvp, hvp_num) # Check that wrong inputs raise an exception. assert_raises(ValueError, sdtw_hessian_product_C, P, E, X) assert_raises(ValueError, sdtw_hessian_product_C, P, X, V_dot)
def f(X, Y): C = squared_euclidean_cost(X, Y, log=True) return sdtw_C(C)