#include #include #include #include "pcg-cpp/include/pcg_random.hpp" #include "randutils/randutils.hpp" template using Vector = Eigen::Matrix; template using Matrix = Eigen::Matrix; template class Model { private: Matrix A; Vector b; public: template Model(Real σ, unsigned N, unsigned M, Generator& r) : A(M, N), b(M) { std::normal_distribution aDistribution(0, 1); for (unsigned i = 0; i < M; i++) { for (unsigned j =0; j < N; j++) { A(i, j) = aDistribution(r); } } std::normal_distribution bDistribution(0, σ); for (unsigned i = 0; i < M; i++) { b(i) = bDistribution(r); } } const unsigned N() { return A.cols(); } const unsigned M() { return A.rows(); } const Vector V(const Vector& x) { return A * x + b; } const Matrix dV(const Vector& x) { return A; } // const Real ddV(const Vector& x) { // return Matrix::Zero(; // } const Real H(const Vector& x) { return V(x).squaredNorm(); } const Vector dH(const Vector& x) { return dV(x).transpose() * V(x); } const Matrix ddH(const Vector& x) { return dV(x).transpose() * dV(x); } const Vector ∇H(const Vector& x){ return dH(x) - dH(x).dot(x) * x / x.squaredNorm(); } const Matrix HessH(const Vector& x) { Matrix hess = ddH(x) - x.dot(dH(x)) * Matrix::Identity(N(), N()); return hess - (hess * x) * x.transpose() / x.squaredNorm(); } }; using Rng = randutils::random_generator; using Real = double; int main(int argc, char* argv[]) { unsigned N = 10; unsigned M = 10; Real σ = 1; int opt; while ((opt = getopt(argc, argv, "N:M:s:")) != -1) { switch (opt) { case 'N': N = (unsigned)atof(optarg); break; case 'M': M = (unsigned)atof(optarg); break; case 's': σ = atof(optarg); break; default: exit(1); } } Rng r; Model leastSquares(σ, N, M, r.engine()); Vector x = Vector::Zero(N); x(0) = N; std::cout << leastSquares.H(x) << std::endl; std::cout << leastSquares.∇H(x) << std::endl; std::cout << leastSquares.HessH(x) << std::endl; return 0; }