Files
FESADev/tests/test_math_module_includes.cpp
T
2026-05-05 01:16:26 +09:00

72 lines
2.5 KiB
C++

#include "fesa/Math/Math.hpp"
#include <cmath>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <vector>
namespace {
void check(bool value, const char* message) {
if (!value) {
throw std::runtime_error(message);
}
}
void checkNear(fesa::Real actual, fesa::Real expected, fesa::Real tolerance, const char* message) {
if (std::fabs(actual - expected) > tolerance) {
throw std::runtime_error(message);
}
}
} // namespace
int main() {
static_assert(std::is_same_v<fesa::SparseIndex, std::int64_t>, "SparseIndex must remain int64");
static_assert(std::is_same_v<fesa::EquationId, std::int64_t>, "EquationId must remain int64");
const fesa::Vec3 x{1.0, 0.0, 0.0};
const fesa::Vec3 y{0.0, 1.0, 0.0};
const auto z = fesa::cross(x, y);
checkNear(fesa::dot(x, y), 0.0, 1.0e-12, "Vector dot product changed");
checkNear(z.z, 1.0, 1.0e-12, "Vector cross product changed");
checkNear(fesa::norm(fesa::Vec3{3.0, 4.0, 0.0}), 5.0, 1.0e-12, "Vector norm changed");
check(fesa::normalizedIfValid(fesa::Vec3{0.0, 0.0, 0.0}) == std::nullopt, "Invalid normalization changed");
fesa::SparsePattern pattern;
pattern.equation_count = 3;
pattern.entries.push_back({0, 0});
pattern.entries.push_back({0, 2});
check(pattern.nonzeroCount() == 2, "Sparse nonzero count changed");
check(pattern.contains(0, 2), "Sparse pattern lookup changed");
check(!pattern.contains(2, 0), "Sparse pattern lookup became nondirectional");
fesa::DenseMatrix matrix(2, 2);
matrix(0, 0) = 2.0;
matrix(0, 1) = 1.0;
matrix(1, 0) = 1.0;
matrix(1, 1) = 3.0;
const auto product = matrix.multiply({1.0, 2.0});
checkNear(product[0], 4.0, 1.0e-12, "DenseMatrix multiply row 0 changed");
checkNear(product[1], 7.0, 1.0e-12, "DenseMatrix multiply row 1 changed");
const fesa::LinearSolver& solver = fesa::GaussianEliminationSolver{};
const auto solved = solver.solve(matrix, {1.0, 2.0});
check(solved.ok(), "Gaussian solver unexpectedly failed");
checkNear(solved.x[0], 0.2, 1.0e-12, "Gaussian solver x0 changed");
checkNear(solved.x[1], 0.6, 1.0e-12, "Gaussian solver x1 changed");
fesa::DenseMatrix singular(2, 2);
singular(0, 0) = 1.0;
singular(0, 1) = 2.0;
singular(1, 0) = 2.0;
singular(1, 1) = 4.0;
const auto failed = solver.solve(singular, {1.0, 2.0});
check(!failed.ok(), "Singular solve unexpectedly passed");
check(fesa::containsDiagnostic(failed.diagnostics, "FESA-SINGULAR-SOLVER"), "Singular diagnostic code changed");
return 0;
}