From 95f949de6753af534e2ef00044daed9687d57c1f Mon Sep 17 00:00:00 2001 From: Huangzizhou Date: Thu, 23 Nov 2023 14:45:19 -0500 Subject: [PATCH] finish todos in box constraint solver --- src/polysolve/Utils.hpp | 47 ++++++++++++++++++- .../nonlinear/BoxConstraintSolver.cpp | 44 ++++------------- 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/polysolve/Utils.hpp b/src/polysolve/Utils.hpp index f9eaf10..fda3aa8 100644 --- a/src/polysolve/Utils.hpp +++ b/src/polysolve/Utils.hpp @@ -60,4 +60,49 @@ namespace polysolve Eigen::SparseMatrix sparse_identity(int rows, int cols); -} // namespace polysolve \ No newline at end of file +} // namespace polysolve + +namespace nlohmann +{ + template + struct adl_serializer> + { + static void to_json(json &j, const Eigen::Matrix &matrix) + { + for (int row = 0; row < matrix.rows(); ++row) + { + json column = json::array(); + for (int col = 0; col < matrix.cols(); ++col) + { + column.push_back(matrix(row, col)); + } + j.push_back(column); + } + } + + static void from_json(const json &j, Eigen::Matrix &matrix) + { + using Scalar = typename Eigen::Matrix::Scalar; + assert(j.size() > 0); + assert(nrows >= j.size() || nrows == -1); + assert(j.at(0).is_number() || ncols == -1 || ncols >= j.at(0).size()); + + const int n_cols = j.at(0).is_number() ? 1 : j.at(0).size(); + if (nrows == -1 || ncols == -1) + matrix.setZero(j.size(), n_cols); + + for (std::size_t row = 0; row < j.size(); ++row) + { + const auto& jrow = j.at(row); + if (jrow.is_number()) + matrix(row) = jrow; + else + for (std::size_t col = 0; col < jrow.size(); ++col) + { + const auto& value = jrow.at(col); + matrix(row, col) = value.get(); + } + } + } + }; +} // namespace nlohmann \ No newline at end of file diff --git a/src/polysolve/nonlinear/BoxConstraintSolver.cpp b/src/polysolve/nonlinear/BoxConstraintSolver.cpp index f375af2..d40c3f5 100644 --- a/src/polysolve/nonlinear/BoxConstraintSolver.cpp +++ b/src/polysolve/nonlinear/BoxConstraintSolver.cpp @@ -78,40 +78,12 @@ namespace polysolve::nonlinear json box_constraint_params = solver_params["box_constraints"]; if (box_constraint_params["max_change"] > 0) max_change_val_ = box_constraint_params["max_change"]; - // todo - // else - // nlohmann::adl_serializer::from_json(box_constraint_params["max_change"], max_change_); + else + max_change_ = box_constraint_params["max_change"]; - if (box_constraint_params.contains("bounds")) + if (box_constraint_params.contains("bounds") && box_constraint_params["bounds"].is_array() && box_constraint_params["bounds"].size() == 2) { - if (box_constraint_params["bounds"].is_string()) - { - if (std::filesystem::is_regular_file(box_constraint_params["bounds"].get())) - { - // todo - // polyfem::io::read_matrix(box_constraint_params["bounds"].get(), bounds_); - assert(bounds_.cols() == 2); - } - } - else if (box_constraint_params["bounds"].is_array() && box_constraint_params["bounds"].size() == 2) - { - if (box_constraint_params["bounds"][0].is_number()) - { - bounds_.setZero(1, 2); - bounds_ << box_constraint_params["bounds"][0], box_constraint_params["bounds"][1]; - } - else if (box_constraint_params["bounds"][0].is_array()) - { - bounds_.setZero(box_constraint_params["bounds"][0].size(), 2); - Eigen::VectorXd tmp; - // todo - // nlohmann::adl_serializer::from_json(box_constraint_params["bounds"][0], tmp); - bounds_.col(0) = tmp; - // todo - // nlohmann::adl_serializer::from_json(box_constraint_params["bounds"][1], tmp); - bounds_.col(1) = tmp; - } - } + bounds_ = box_constraint_params["bounds"]; } } @@ -149,8 +121,8 @@ namespace polysolve::nonlinear bool consider_max_change) const { Eigen::VectorXd min; - if (bounds_.rows() == x.size()) - min = bounds_.col(0); + if (bounds_.cols() == x.size()) + min = bounds_.row(0); else if (bounds_.size() == 2) min = Eigen::VectorXd::Constant(x.size(), 1, bounds_(0)); else @@ -166,8 +138,8 @@ namespace polysolve::nonlinear bool consider_max_change) const { Eigen::VectorXd max; - if (bounds_.rows() == x.size()) - max = bounds_.col(1); + if (bounds_.cols() == x.size()) + max = bounds_.row(1); else if (bounds_.size() == 2) max = Eigen::VectorXd::Constant(x.size(), 1, bounds_(1)); else