mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2026-01-11 18:34:07 -05:00
COMP: Replace toddcox-faster by reimplemented toddcox
This commit is contained in:
18
tc/test/CMakeLists.txt
Normal file
18
tc/test/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
include(GoogleTest)
|
||||
|
||||
add_executable(test_solve test_solve.cpp)
|
||||
target_link_libraries(test_solve tc GTest::gtest_main)
|
||||
|
||||
add_executable(test_lang test_lang.cpp)
|
||||
target_link_libraries(test_lang PUBLIC tc::tc GTest::gtest_main)
|
||||
|
||||
set(MIN_DEBUG_CPS 200000)
|
||||
set(MIN_RELEASE_CPS 1000000)
|
||||
|
||||
target_compile_definitions(
|
||||
test_solve PUBLIC
|
||||
MIN_COS_PER_SEC=$<IF:$<CONFIG:Debug>,${MIN_DEBUG_CPS},${MIN_RELEASE_CPS}>
|
||||
)
|
||||
|
||||
gtest_discover_tests(test_solve)
|
||||
gtest_discover_tests(test_lang)
|
||||
54
tc/test/test_lang.cpp
Normal file
54
tc/test/test_lang.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <tc/core.hpp>
|
||||
#include <tc/groups.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// "5 3 3"
|
||||
// "5 (3 3)"
|
||||
// "[5 3 3]"
|
||||
// "[4 3 [3 5] 3]"
|
||||
// "{3 4 5 6 7 8 9}"
|
||||
// "3 {3 3 [4] 3} 5"
|
||||
// "5 * 3"
|
||||
// "5 * [3]"
|
||||
// "5 * {2 3}"
|
||||
// "5 * [3 2]"
|
||||
// "(5 2) * [3 2]"
|
||||
// "4 [3 * [2 3]] 5"
|
||||
// "{3 * 3} [4] [5]"
|
||||
|
||||
TEST(coxeter, simple) {
|
||||
auto g = tc::coxeter("5 3 3");
|
||||
|
||||
ASSERT_EQ(g.rank(), 4);
|
||||
|
||||
EXPECT_EQ(g.get(0, 0), 1);
|
||||
EXPECT_EQ(g.get(0, 1), 5);
|
||||
EXPECT_EQ(g.get(0, 2), 2);
|
||||
EXPECT_EQ(g.get(0, 3), 2);
|
||||
|
||||
EXPECT_EQ(g.get(1, 0), 5);
|
||||
EXPECT_EQ(g.get(1, 1), 1);
|
||||
EXPECT_EQ(g.get(1, 2), 3);
|
||||
EXPECT_EQ(g.get(1, 3), 2);
|
||||
|
||||
EXPECT_EQ(g.get(2, 0), 2);
|
||||
EXPECT_EQ(g.get(2, 1), 3);
|
||||
EXPECT_EQ(g.get(2, 2), 1);
|
||||
EXPECT_EQ(g.get(2, 3), 3);
|
||||
|
||||
EXPECT_EQ(g.get(3, 0), 2);
|
||||
EXPECT_EQ(g.get(3, 1), 2);
|
||||
EXPECT_EQ(g.get(3, 2), 3);
|
||||
EXPECT_EQ(g.get(3, 3), 1);
|
||||
}
|
||||
|
||||
TEST(coxeter, looping) {
|
||||
auto g = tc::coxeter("{5 3 4}");
|
||||
|
||||
ASSERT_EQ(g.rank(), 3);
|
||||
|
||||
EXPECT_EQ(g.get(0, 1), 5);
|
||||
EXPECT_EQ(g.get(1, 2), 3);
|
||||
EXPECT_EQ(g.get(2, 0), 4);
|
||||
}
|
||||
225
tc/test/test_solve.cpp
Normal file
225
tc/test/test_solve.cpp
Normal file
@@ -0,0 +1,225 @@
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
|
||||
#include <tc/groups.hpp>
|
||||
#include <tc/core.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
/// helper for testing solve and testing speed
|
||||
testing::AssertionResult AssertSolveOrder(
|
||||
const char *group_expr,
|
||||
const char *sub_gens_expr,
|
||||
const char *expected_order_expr,
|
||||
const tc::Group<> &group,
|
||||
const std::vector<size_t> &sub_gens,
|
||||
size_t expected_order
|
||||
) {
|
||||
auto start = std::clock();
|
||||
auto cosets = group.solve(sub_gens);
|
||||
auto end = std::clock();
|
||||
|
||||
size_t actual_order = cosets.order();
|
||||
|
||||
auto total_sec = (double) (end - start) / CLOCKS_PER_SEC;
|
||||
auto cosets_per_sec = (double) actual_order / total_sec;
|
||||
|
||||
bool order_good = actual_order == expected_order;
|
||||
bool speed_good = cosets_per_sec >= MIN_COS_PER_SEC || total_sec < 0.0001;
|
||||
// extremely short times cause false negatives. ex. A2 can be solved in only 3 clocks.
|
||||
|
||||
if (order_good && speed_good) {
|
||||
return testing::AssertionSuccess();
|
||||
}
|
||||
|
||||
testing::AssertionResult res = testing::AssertionFailure();
|
||||
res << group_expr << " / " << sub_gens_expr << " :";
|
||||
if (!order_good) {
|
||||
res << " Gave order " << actual_order << " but expected order " << expected_order << ".";
|
||||
}
|
||||
if (!speed_good) {
|
||||
res << " Solution too slow (" << cosets_per_sec
|
||||
<< " cos/s < " << MIN_COS_PER_SEC << ")."
|
||||
<< " " << std::fixed << total_sec << " s.";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define EXPECT_SOLVE_ORDER(group, sub_gens, expected_order) EXPECT_PRED_FORMAT3(AssertSolveOrder, group, sub_gens, expected_order);
|
||||
|
||||
using v = std::vector<size_t>;
|
||||
|
||||
tc::Group<> A(unsigned int n) {
|
||||
return tc::vcoxeter("3 * {}", {n - 1});
|
||||
}
|
||||
|
||||
tc::Group<> B(unsigned int n) {
|
||||
return tc::vcoxeter("4 3 * {}", {n - 2});
|
||||
}
|
||||
|
||||
tc::Group<> D(unsigned int n) {
|
||||
return tc::vcoxeter("3 * [1 1 {}]", {n - 3});
|
||||
}
|
||||
|
||||
tc::Group<> E(unsigned int n) {
|
||||
return tc::vcoxeter("3 * [1 2 {}]", {n - 4});
|
||||
}
|
||||
|
||||
tc::Group<> F4() {
|
||||
return tc::coxeter("3 4 3");
|
||||
}
|
||||
|
||||
tc::Group<> G2() {
|
||||
return tc::coxeter("6");
|
||||
}
|
||||
|
||||
tc::Group<> H(unsigned int n) {
|
||||
return tc::vcoxeter("5 3 * {}", {n - 2});
|
||||
}
|
||||
|
||||
tc::Group<> I2(unsigned int n) {
|
||||
return tc::vcoxeter("{}", {n});
|
||||
}
|
||||
|
||||
tc::Group<> T(unsigned int m, unsigned int n) {
|
||||
return tc::vcoxeter("{} 2 {}", {m, n});
|
||||
}
|
||||
|
||||
tc::Group<> T(unsigned int n) {
|
||||
return T(n, n);
|
||||
}
|
||||
|
||||
// See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties
|
||||
|
||||
TEST(solve, A) {
|
||||
EXPECT_SOLVE_ORDER(A(1), v({}), 2);
|
||||
EXPECT_SOLVE_ORDER(A(2), v({}), 6);
|
||||
EXPECT_SOLVE_ORDER(A(3), v({}), 24);
|
||||
EXPECT_SOLVE_ORDER(A(3), v({0}), 12);
|
||||
EXPECT_SOLVE_ORDER(A(3), v({0, 1}), 4);
|
||||
EXPECT_SOLVE_ORDER(A(3), v({0, 2}), 6);
|
||||
EXPECT_SOLVE_ORDER(A(3), v({2}), 12);
|
||||
EXPECT_SOLVE_ORDER(A(4), v({}), 120);
|
||||
EXPECT_SOLVE_ORDER(A(4), v({0}), 60);
|
||||
EXPECT_SOLVE_ORDER(A(4), v({0, 1}), 20);
|
||||
EXPECT_SOLVE_ORDER(A(4), v({2}), 60);
|
||||
EXPECT_SOLVE_ORDER(A(4), v({0, 2}), 30);
|
||||
}
|
||||
|
||||
TEST(solve, B) {
|
||||
EXPECT_SOLVE_ORDER(B(2), v({}), 8);
|
||||
EXPECT_SOLVE_ORDER(B(3), v({}), 48);
|
||||
EXPECT_SOLVE_ORDER(B(3), v({0}), 24);
|
||||
EXPECT_SOLVE_ORDER(B(3), v({0, 2}), 12);
|
||||
EXPECT_SOLVE_ORDER(B(4), v({}), 384);
|
||||
EXPECT_SOLVE_ORDER(B(4), v({0}), 192);
|
||||
EXPECT_SOLVE_ORDER(B(4), v({0, 2}), 96);
|
||||
EXPECT_SOLVE_ORDER(B(5), v({}), 3840);
|
||||
EXPECT_SOLVE_ORDER(B(5), v({0}), 1920);
|
||||
EXPECT_SOLVE_ORDER(B(5), v({0, 2}), 960);
|
||||
EXPECT_SOLVE_ORDER(B(5), v({0, 2, 3}), 320);
|
||||
EXPECT_SOLVE_ORDER(B(6), v({}), 46080);
|
||||
EXPECT_SOLVE_ORDER(B(6), v({0}), 23040);
|
||||
EXPECT_SOLVE_ORDER(B(6), v({0, 2}), 11520);
|
||||
EXPECT_SOLVE_ORDER(B(6), v({0, 2, 3}), 3840);
|
||||
EXPECT_SOLVE_ORDER(B(6), v({0, 2, 3, 5}), 1920);
|
||||
}
|
||||
|
||||
TEST(solve, D) {
|
||||
EXPECT_SOLVE_ORDER(D(3), v({}), 24);
|
||||
EXPECT_SOLVE_ORDER(D(4), v({}), 192);
|
||||
EXPECT_SOLVE_ORDER(D(4), v({0, 1}), 32);
|
||||
EXPECT_SOLVE_ORDER(D(4), v({0, 1, 3}), 8);
|
||||
EXPECT_SOLVE_ORDER(D(5), v({}), 1920);
|
||||
EXPECT_SOLVE_ORDER(D(5), v({0, 1}), 320);
|
||||
EXPECT_SOLVE_ORDER(D(5), v({0, 1, 3}), 80);
|
||||
EXPECT_SOLVE_ORDER(D(5), v({0, 1, 3, 4}), 16);
|
||||
EXPECT_SOLVE_ORDER(D(6), v({}), 23040);
|
||||
EXPECT_SOLVE_ORDER(D(6), v({0, 1}), 3840);
|
||||
EXPECT_SOLVE_ORDER(D(6), v({0, 1, 3}), 960);
|
||||
EXPECT_SOLVE_ORDER(D(6), v({0, 1, 3, 5}), 480);
|
||||
}
|
||||
|
||||
TEST(solve, E) {
|
||||
EXPECT_SOLVE_ORDER(E(4), v({}), 120);
|
||||
EXPECT_SOLVE_ORDER(E(4), v({2}), 60);
|
||||
EXPECT_SOLVE_ORDER(E(4), v({2, 1}), 30);
|
||||
EXPECT_SOLVE_ORDER(E(4), v({2, 1, 3}), 10);
|
||||
EXPECT_SOLVE_ORDER(E(5), v({}), 1920);
|
||||
EXPECT_SOLVE_ORDER(E(5), v({2}), 960);
|
||||
EXPECT_SOLVE_ORDER(E(5), v({2, 1}), 480);
|
||||
EXPECT_SOLVE_ORDER(E(5), v({2, 1, 3}), 160);
|
||||
EXPECT_SOLVE_ORDER(E(6), v({}), 51840);
|
||||
EXPECT_SOLVE_ORDER(E(6), v({2}), 25920);
|
||||
EXPECT_SOLVE_ORDER(E(6), v({2, 1}), 12960);
|
||||
EXPECT_SOLVE_ORDER(E(6), v({2, 1, 3}), 4320);
|
||||
}
|
||||
|
||||
TEST(solve, F) {
|
||||
EXPECT_SOLVE_ORDER(F4(), v({}), 1152);
|
||||
EXPECT_SOLVE_ORDER(F4(), v({0}), 576);
|
||||
EXPECT_SOLVE_ORDER(F4(), v({0, 2}), 288);
|
||||
EXPECT_SOLVE_ORDER(F4(), v({1, 3}), 288);
|
||||
EXPECT_SOLVE_ORDER(F4(), v({1, 2, 3}), 24);
|
||||
}
|
||||
|
||||
TEST(solve, G) {
|
||||
EXPECT_SOLVE_ORDER(G2(), v({}), 12);
|
||||
EXPECT_SOLVE_ORDER(G2(), v({0}), 6);
|
||||
EXPECT_SOLVE_ORDER(G2(), v({1}), 6);
|
||||
}
|
||||
|
||||
TEST(solve, H) {
|
||||
EXPECT_SOLVE_ORDER(H(2), v({}), 10);
|
||||
EXPECT_SOLVE_ORDER(H(2), v({0}), 5);
|
||||
EXPECT_SOLVE_ORDER(H(2), v({1}), 5);
|
||||
EXPECT_SOLVE_ORDER(H(3), v({}), 120);
|
||||
EXPECT_SOLVE_ORDER(H(3), v({0}), 60);
|
||||
EXPECT_SOLVE_ORDER(H(3), v({0, 1}), 12);
|
||||
EXPECT_SOLVE_ORDER(H(3), v({0, 2}), 30);
|
||||
EXPECT_SOLVE_ORDER(H(3), v({1, 2}), 20);
|
||||
EXPECT_SOLVE_ORDER(H(4), v({}), 14400);
|
||||
EXPECT_SOLVE_ORDER(H(4), v({0}), 7200);
|
||||
EXPECT_SOLVE_ORDER(H(4), v({1}), 7200);
|
||||
EXPECT_SOLVE_ORDER(H(4), v({1, 3}), 3600);
|
||||
}
|
||||
|
||||
TEST(solve, I) {
|
||||
EXPECT_SOLVE_ORDER(I2(2), v({}), 4);
|
||||
EXPECT_SOLVE_ORDER(I2(3), v({}), 6);
|
||||
EXPECT_SOLVE_ORDER(I2(3), v({0}), 3);
|
||||
EXPECT_SOLVE_ORDER(I2(3), v({1}), 3);
|
||||
EXPECT_SOLVE_ORDER(I2(4), v({}), 8);
|
||||
EXPECT_SOLVE_ORDER(I2(4), v({0}), 4);
|
||||
EXPECT_SOLVE_ORDER(I2(4), v({1}), 4);
|
||||
EXPECT_SOLVE_ORDER(I2(5), v({}), 10);
|
||||
EXPECT_SOLVE_ORDER(I2(5), v({0}), 5);
|
||||
EXPECT_SOLVE_ORDER(I2(5), v({1}), 5);
|
||||
}
|
||||
|
||||
TEST(solve, T) {
|
||||
EXPECT_SOLVE_ORDER(T(3), v({}), 36);
|
||||
EXPECT_SOLVE_ORDER(T(4), v({}), 64);
|
||||
EXPECT_SOLVE_ORDER(T(400), v({}), 640000);
|
||||
EXPECT_SOLVE_ORDER(T(400), v({0}), 320000);
|
||||
EXPECT_SOLVE_ORDER(T(400), v({0, 2}), 160000);
|
||||
EXPECT_SOLVE_ORDER(T(400, 300), v({}), 480000);
|
||||
EXPECT_SOLVE_ORDER(T(400, 300), v({0}), 240000);
|
||||
EXPECT_SOLVE_ORDER(T(400, 300), v({0, 2}), 120000);
|
||||
}
|
||||
|
||||
TEST(solve_large, B) {
|
||||
EXPECT_SOLVE_ORDER(B(7), v({}), 645120);
|
||||
EXPECT_SOLVE_ORDER(B(8), v({}), 10321920);
|
||||
}
|
||||
|
||||
TEST(solve_large, E) {
|
||||
EXPECT_SOLVE_ORDER(E(6), v({}), 51840);
|
||||
EXPECT_SOLVE_ORDER(E(7), v({}), 2903040);
|
||||
}
|
||||
|
||||
TEST(solve_large, T) {
|
||||
EXPECT_SOLVE_ORDER(T(500), v({}), 1000000);
|
||||
EXPECT_SOLVE_ORDER(T(1000), v({}), 4000000);
|
||||
}
|
||||
Reference in New Issue
Block a user