add blts
This commit is contained in:
+42
-36
@@ -50,58 +50,63 @@ TEST(DualTest, DerivativeFunction) {
|
||||
}
|
||||
|
||||
TEST(DualTest, GradientFunction) {
|
||||
auto func = []<typename T>(const std::array<T, 2>& x) {
|
||||
return x[0] * x[0] + std::sin(x[1]);
|
||||
auto func = []<typename T>(const Eigen::VectorX<T>& x) {
|
||||
return x(0) * x(0) + std::sin(x(1));
|
||||
};
|
||||
|
||||
std::array<double, 2> point = {1.0, 0.0};
|
||||
std::array<double, 2> grad = gradient(func, point);
|
||||
Eigen::VectorX<double> point(2);
|
||||
point << 1.0, 0.0;
|
||||
Eigen::VectorX<double> grad = gradient(func, point);
|
||||
|
||||
EXPECT_DOUBLE_EQ(grad[0], 2.0 * point[0]); // d/dx1
|
||||
EXPECT_DOUBLE_EQ(grad[1], std::cos(point[1])); // d/dx2
|
||||
EXPECT_DOUBLE_EQ(grad(0), 2.0 * point(0)); // d/dx1
|
||||
EXPECT_DOUBLE_EQ(grad(1), std::cos(point(1))); // d/dx2
|
||||
}
|
||||
|
||||
TEST(DualTest, JacobianFunction) {
|
||||
auto func = []<typename T>(const std::array<T, 2>& x) {
|
||||
return std::array<T, 2>{x[0] * x[0], std::sin(x[1])};
|
||||
auto func = []<typename T>(const Eigen::VectorX<T>& x) {
|
||||
Eigen::VectorX<T> y(2);
|
||||
y << x(0) * x(0), std::sin(x(1));
|
||||
return y;
|
||||
};
|
||||
|
||||
std::array<double, 2> point = {1.0, 0.0};
|
||||
auto jacob = jacobian<double, 2, 2>(func, point);
|
||||
Eigen::VectorX<double> point(2);
|
||||
point << 1.0, 0.0;
|
||||
auto jacob = jacobian<double>(func, point);
|
||||
|
||||
EXPECT_DOUBLE_EQ(jacob[0][0], 2.0 * point[0]); // d(f1)/d(x1)
|
||||
EXPECT_DOUBLE_EQ(jacob[0][1], 0.0); // d(f1)/d(x2)
|
||||
EXPECT_DOUBLE_EQ(jacob[1][0], 0.0); // d(f2)/d(x1)
|
||||
EXPECT_DOUBLE_EQ(jacob[1][1], std::cos(point[1])); // d(f2)/d(x2)
|
||||
EXPECT_DOUBLE_EQ(jacob(0, 0), 2.0 * point(0)); // d(f1)/d(x1)
|
||||
EXPECT_DOUBLE_EQ(jacob(0, 1), 0.0); // d(f1)/d(x2)
|
||||
EXPECT_DOUBLE_EQ(jacob(1, 0), 0.0); // d(f2)/d(x1)
|
||||
EXPECT_DOUBLE_EQ(jacob(1, 1), std::cos(point(1))); // d(f2)/d(x2)
|
||||
}
|
||||
|
||||
TEST(DualTest, HessianFunction) {
|
||||
auto func = []<typename T>(const std::array<T, 2>& x) {
|
||||
return x[0] * x[0] + x[1] * x[1];
|
||||
auto func = []<typename T>(const Eigen::VectorX<T>& x) {
|
||||
return x(0) * x(0) + x(1) * x(1);
|
||||
};
|
||||
|
||||
std::array<double, 2> point = {1.0, 2.0};
|
||||
auto hess = hessian<double, 2>(func, point);
|
||||
Eigen::VectorX<double> point(2);
|
||||
point << 1.0, 2.0;
|
||||
auto hess = hessian<double>(func, point);
|
||||
|
||||
EXPECT_DOUBLE_EQ(hess[0][0], 2.0); // d²f/dx1²
|
||||
EXPECT_DOUBLE_EQ(hess[0][1], 0.0); // d²f/dx1dx2
|
||||
EXPECT_DOUBLE_EQ(hess[1][0], 0.0); // d²f/dx2dx1
|
||||
EXPECT_DOUBLE_EQ(hess[1][1], 2.0); // d²f/dx2²
|
||||
EXPECT_DOUBLE_EQ(hess(0, 0), 2.0); // d²f/dx1²
|
||||
EXPECT_DOUBLE_EQ(hess(0, 1), 0.0); // d²f/dx1dx2
|
||||
EXPECT_DOUBLE_EQ(hess(1, 0), 0.0); // d²f/dx2dx1
|
||||
EXPECT_DOUBLE_EQ(hess(1, 1), 2.0); // d²f/dx2²
|
||||
}
|
||||
|
||||
struct opti_func {
|
||||
std::vector<std::array<double, 2>> test_data;
|
||||
std::vector<Eigen::Vector2<double>> test_data;
|
||||
|
||||
// loss function
|
||||
template <typename T>
|
||||
T operator()(const std::array<T, 3>& params) const {
|
||||
T operator()(const Eigen::VectorX<T>& params) const {
|
||||
T sum = T(0);
|
||||
for (const auto& data_point : test_data) {
|
||||
T x = T{data_point[0]};
|
||||
T y_true = T{data_point[1]};
|
||||
T a = params[0];
|
||||
T b = params[1];
|
||||
T c = params[2];
|
||||
T x = T{data_point(0)};
|
||||
T y_true = T{data_point(1)};
|
||||
T a = params(0);
|
||||
T b = params(1);
|
||||
T c = params(2);
|
||||
T y_pred = a * x * x + b * x + c;
|
||||
T error = y_pred - y_true;
|
||||
sum = sum + error * error;
|
||||
@@ -120,18 +125,19 @@ TEST(DualTest, OptimizationFunction) {
|
||||
{4.0, 4.0},
|
||||
};
|
||||
|
||||
std::array<double, 3> params = {1.0, -4.0, 4.0};
|
||||
Eigen::VectorX<double> params(3);
|
||||
params << 1.0, -4.0, 4.0;
|
||||
|
||||
auto grad = gradient<double, 3>(f, params);
|
||||
auto grad = gradient<double>(f, params);
|
||||
|
||||
EXPECT_DOUBLE_EQ(grad[0], 0.0); // dL/da
|
||||
EXPECT_DOUBLE_EQ(grad[1], 0.0); // dL/db
|
||||
EXPECT_DOUBLE_EQ(grad[2], 0.0); // dL/dc
|
||||
EXPECT_DOUBLE_EQ(grad(0), 0.0); // dL/da
|
||||
EXPECT_DOUBLE_EQ(grad(1), 0.0); // dL/db
|
||||
EXPECT_DOUBLE_EQ(grad(2), 0.0); // dL/dc
|
||||
|
||||
auto hess = hessian<double, 3>(f, params);
|
||||
auto hess = hessian<double>(f, params);
|
||||
for (std::size_t i = 0; i < 3; ++i) {
|
||||
for (std::size_t j = 0; j < 3; ++j) {
|
||||
EXPECT_GE(hess[i][j], 0.0); // Hessian should be positive semi-definite
|
||||
EXPECT_GE(hess(i, j), 0.0); // Hessian should be positive semi-definite
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user