| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifdef _MSC_VER |
| | # pragma warning(disable : 4251) |
| | # pragma warning(disable : 4244) |
| | # pragma warning(disable : 4996) |
| | #endif |
| |
|
| | #undef _GCS_DEBUG |
| | #undef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | #undef _DEBUG_TO_FILE |
| |
|
| | |
| | |
| | #ifdef _GCS_DEBUG |
| | # define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat(3, 0, ",", ",\n", "[", "]", "[", "]") |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #endif |
| |
|
| | #include <algorithm> |
| | #include <future> |
| | #include <iostream> |
| | #include <limits> |
| | #include <numbers> |
| |
|
| | #include "GCS.h" |
| | #include "qp_eq.h" |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | |
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | # if EIGEN_VERSION >= 30304 |
| | # define SPARSE_Q_MATRIX |
| | # endif |
| | #endif |
| |
|
| | #if EIGEN_VERSION > 30290 |
| | |
| | |
| | |
| | |
| | # define EIGEN_STOCK_FULLPIVLU_COMPUTE |
| | #endif |
| |
|
| | |
| |
|
| |
|
| | #ifdef EIGEN_SPARSEQR_COMPATIBLE |
| | # include <Eigen/OrderingMethods> |
| | #endif |
| |
|
| | |
| | #if defined(_GCS_EXTRACT_SOLVER_SUBSYSTEM_) || defined(_DEBUG_TO_FILE) |
| | # include <fstream> |
| |
|
| | # define CASE_NOT_IMP(X) \ |
| | case X: { \ |
| | subsystemfile << "//" #X "not yet implemented" << std::endl; \ |
| | break; \ |
| | } |
| | #endif |
| |
|
| | #include <Base/Console.h> |
| | #include <FCConfig.h> |
| |
|
| | #include <boost/graph/connected_components.hpp> |
| | #include <boost_graph_adjacency_list.hpp> |
| |
|
| | using MatrixIndexType = Eigen::FullPivHouseholderQR<Eigen::MatrixXd>::IntDiagSizeVectorType; |
| |
|
| | #ifndef EIGEN_STOCK_FULLPIVLU_COMPUTE |
| | namespace Eigen |
| | { |
| |
|
| | using MatrixdType = Matrix<double, -1, -1, 0, -1, -1>; |
| |
|
| | template<> |
| | FullPivLU<MatrixdType>& FullPivLU<MatrixdType>::compute(const MatrixdType& matrix) |
| | { |
| | m_isInitialized = true; |
| | m_lu = matrix; |
| |
|
| | const Index size = matrix.diagonalSize(); |
| | const Index rows = matrix.rows(); |
| | const Index cols = matrix.cols(); |
| |
|
| | |
| | |
| | m_rowsTranspositions.resize(matrix.rows()); |
| | m_colsTranspositions.resize(matrix.cols()); |
| | |
| | Index number_of_transpositions = 0; |
| |
|
| | |
| | m_nonzero_pivots = size; |
| | m_maxpivot = RealScalar(0); |
| | RealScalar cutoff(0); |
| |
|
| | for (Index k = 0; k < size; ++k) { |
| | |
| |
|
| | |
| | Index row_of_biggest_in_corner, col_of_biggest_in_corner; |
| | RealScalar biggest_in_corner; |
| | biggest_in_corner = m_lu.bottomRightCorner(rows - k, cols - k) |
| | .cwiseAbs() |
| | .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner); |
| |
|
| | |
| | row_of_biggest_in_corner += k; |
| | col_of_biggest_in_corner += k; |
| |
|
| | |
| | |
| | if (k == 0) { |
| | cutoff = biggest_in_corner * NumTraits<Scalar>::epsilon(); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | if (biggest_in_corner < cutoff) { |
| | |
| | |
| | m_nonzero_pivots = k; |
| | for (Index i = k; i < size; ++i) { |
| | m_rowsTranspositions.coeffRef(i) = i; |
| | m_colsTranspositions.coeffRef(i) = i; |
| | } |
| | break; |
| | } |
| |
|
| | if (biggest_in_corner > m_maxpivot) { |
| | m_maxpivot = biggest_in_corner; |
| | } |
| |
|
| | |
| | |
| |
|
| | m_rowsTranspositions.coeffRef(k) = row_of_biggest_in_corner; |
| | m_colsTranspositions.coeffRef(k) = col_of_biggest_in_corner; |
| | if (k != row_of_biggest_in_corner) { |
| | m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner)); |
| | ++number_of_transpositions; |
| | } |
| | if (k != col_of_biggest_in_corner) { |
| | m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner)); |
| | ++number_of_transpositions; |
| | } |
| |
|
| | |
| | |
| |
|
| | if (k < rows - 1) { |
| | m_lu.col(k).tail(rows - k - 1) /= m_lu.coeff(k, k); |
| | } |
| | if (k < size - 1) { |
| | m_lu.block(k + 1, k + 1, rows - k - 1, cols - k - 1).noalias() |
| | -= m_lu.col(k).tail(rows - k - 1) * m_lu.row(k).tail(cols - k - 1); |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | m_p.setIdentity(rows); |
| | for (Index k = size - 1; k >= 0; --k) { |
| | m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k)); |
| | } |
| |
|
| | m_q.setIdentity(cols); |
| | for (Index k = 0; k < size; ++k) { |
| | m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k)); |
| | } |
| |
|
| | m_det_pq = (number_of_transpositions % 2) ? -1 : 1; |
| | return *this; |
| | } |
| |
|
| | } |
| | #endif |
| |
|
| | namespace GCS |
| | { |
| |
|
| | class SolverReportingManager |
| | { |
| | public: |
| | SolverReportingManager(SolverReportingManager const&) = delete; |
| | SolverReportingManager(SolverReportingManager&&) = delete; |
| | SolverReportingManager& operator=(SolverReportingManager const&) = delete; |
| | SolverReportingManager& operator=(SolverReportingManager&&) = delete; |
| |
|
| | static SolverReportingManager& Manager(); |
| |
|
| | inline void LogString(const std::string& str); |
| |
|
| | inline void LogToConsole(const std::string& str); |
| |
|
| | inline void LogToFile(const std::string& str); |
| |
|
| | void LogQRSystemInformation(const System& system, int paramsNum = 0, int constrNum = 0, int rank = 0); |
| |
|
| | void LogGroupOfConstraints( |
| | const std::string& str, |
| | std::vector<std::vector<Constraint*>> constraintgroups |
| | ); |
| | void LogSetOfConstraints(const std::string& str, std::set<Constraint*> constraintset); |
| | void LogGroupOfParameters(const std::string& str, std::vector<std::vector<double*>> parametergroups); |
| |
|
| | void LogMatrix(const std::string str, Eigen::MatrixXd matrix); |
| | void LogMatrix(const std::string str, MatrixIndexType matrix); |
| |
|
| | private: |
| | SolverReportingManager(); |
| | ~SolverReportingManager(); |
| |
|
| | inline void initStream(); |
| | inline void flushStream(); |
| |
|
| | private: |
| | #ifdef _DEBUG_TO_FILE |
| | std::ofstream stream; |
| | #endif |
| | }; |
| |
|
| | SolverReportingManager::SolverReportingManager() |
| | { |
| | initStream(); |
| | } |
| |
|
| | SolverReportingManager::~SolverReportingManager() |
| | { |
| | #ifdef _DEBUG_TO_FILE |
| | stream.flush(); |
| | stream.close(); |
| | #endif |
| | } |
| |
|
| | void SolverReportingManager::initStream() |
| | { |
| | #ifdef _DEBUG_TO_FILE |
| | if (!stream.is_open()) { |
| | stream.open("GCS_debug.txt", std::ofstream::out | std::ofstream::app); |
| | } |
| | #endif |
| | } |
| |
|
| | void SolverReportingManager::flushStream() |
| | { |
| | |
| | #ifdef _DEBUG_TO_FILE |
| | stream.flush(); |
| | stream.close(); |
| | #endif |
| | } |
| |
|
| | SolverReportingManager& SolverReportingManager::Manager() |
| | { |
| | static SolverReportingManager theInstance; |
| |
|
| | return theInstance; |
| | } |
| |
|
| | void SolverReportingManager::LogToConsole(const std::string& str) |
| | { |
| | Base::Console().log(str.c_str()); |
| | } |
| |
|
| | void SolverReportingManager::LogToFile(const std::string& str) |
| | { |
| | #ifdef _DEBUG_TO_FILE |
| | initStream(); |
| |
|
| | stream << str << std::endl; |
| |
|
| | flushStream(); |
| | #else |
| | (void)(str); |
| | LogToConsole("Debugging to file not enabled!"); |
| | #endif |
| | } |
| |
|
| | void SolverReportingManager::LogString(const std::string& str) |
| | { |
| | LogToConsole(str); |
| |
|
| | #ifdef _DEBUG_TO_FILE |
| | LogToFile(str); |
| | #endif |
| | } |
| |
|
| | void SolverReportingManager::LogQRSystemInformation( |
| | const System& system, |
| | int paramsNum, |
| | int constrNum, |
| | int rank |
| | ) |
| | { |
| |
|
| | std::stringstream tempstream; |
| |
|
| | tempstream |
| | << (system.qrAlgorithm == EigenSparseQR |
| | ? "EigenSparseQR" |
| | : (system.qrAlgorithm == EigenDenseQR ? "DenseQR" : "")); |
| |
|
| | if (paramsNum > 0) { |
| | tempstream |
| | #ifdef EIGEN_SPARSEQR_COMPATIBLE |
| | << ", Threads: " << Eigen::nbThreads() |
| | #endif |
| | #ifdef EIGEN_VECTORIZE |
| | << ", Vectorization: On" |
| | #endif |
| | << ", Pivot Threshold: " << system.qrpivotThreshold << ", Params: " << paramsNum |
| | << ", Constr: " << constrNum << ", Rank: " << rank << std::endl; |
| | } |
| | else { |
| | tempstream |
| | #ifdef EIGEN_SPARSEQR_COMPATIBLE |
| | << ", Threads: " << Eigen::nbThreads() |
| | #endif |
| | #ifdef EIGEN_VECTORIZE |
| | << ", Vectorization: On" |
| | #endif |
| | << ", Empty Sketch, nothing to solve" << std::endl; |
| | } |
| |
|
| | LogString(tempstream.str()); |
| | } |
| |
|
| | void SolverReportingManager::LogGroupOfConstraints( |
| | const std::string& str, |
| | std::vector<std::vector<Constraint*>> constraintgroups |
| | ) |
| | { |
| | std::stringstream tempstream; |
| |
|
| | tempstream << str << ":" << '\n'; |
| |
|
| | for (const auto& group : constraintgroups) { |
| | tempstream << "["; |
| |
|
| | for (auto c : group) { |
| | tempstream << c->getTag() << " "; |
| | } |
| |
|
| | tempstream << "]" << '\n'; |
| | } |
| |
|
| | LogString(tempstream.str()); |
| | } |
| |
|
| | void SolverReportingManager::LogSetOfConstraints( |
| | const std::string& str, |
| | std::set<Constraint*> constraintset |
| | ) |
| | { |
| | std::stringstream tempstream; |
| |
|
| | tempstream << str << ": ["; |
| |
|
| | for (auto c : constraintset) { |
| | tempstream << c->getTag() << " "; |
| | } |
| |
|
| | tempstream << "]" << '\n'; |
| |
|
| | LogString(tempstream.str()); |
| | } |
| |
|
| | void SolverReportingManager::LogGroupOfParameters( |
| | const std::string& str, |
| | std::vector<std::vector<double*>> parametergroups |
| | ) |
| | { |
| | std::stringstream tempstream; |
| |
|
| | tempstream << str << ":" << '\n'; |
| |
|
| | for (size_t i = 0; i < parametergroups.size(); i++) { |
| | tempstream << "["; |
| |
|
| | for (auto p : parametergroups[i]) { |
| | tempstream << std::hex << p << " "; |
| | } |
| |
|
| | tempstream << "]" << '\n'; |
| | } |
| |
|
| | LogString(tempstream.str()); |
| | } |
| |
|
| | #ifdef _GCS_DEBUG |
| | void SolverReportingManager::LogMatrix(const std::string str, Eigen::MatrixXd matrix) |
| | { |
| | std::stringstream tempstream; |
| |
|
| | tempstream << '\n' << " " << str << " =" << '\n'; |
| | tempstream << "[" << '\n'; |
| | tempstream << matrix << '\n'; |
| | tempstream << "]" << '\n'; |
| |
|
| | LogString(tempstream.str()); |
| | } |
| |
|
| | void SolverReportingManager::LogMatrix(const std::string str, MatrixIndexType matrix) |
| | { |
| | std::stringstream tempstream; |
| |
|
| | stream << '\n' << " " << str << " =" << '\n'; |
| | stream << "[" << '\n'; |
| | stream << matrix << '\n'; |
| | stream << "]" << '\n'; |
| |
|
| | LogString(tempstream.str()); |
| | } |
| | #endif |
| |
|
| |
|
| | using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>; |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | System::System() |
| | : plist(0) |
| | , pdrivenlist(0) |
| | , pDependentParameters(0) |
| | , clist(0) |
| | , c2p() |
| | , p2c() |
| | , subSystems(0) |
| | , subSystemsAux(0) |
| | , reference(0) |
| | , dofs(0) |
| | , hasUnknowns(false) |
| | , hasDiagnosis(false) |
| | , isInit(false) |
| | , emptyDiagnoseMatrix(true) |
| | , maxIter(100) |
| | , maxIterRedundant(100) |
| | , sketchSizeMultiplier(false) |
| | , sketchSizeMultiplierRedundant(false) |
| | , convergence(1e-10) |
| | , convergenceRedundant(1e-10) |
| | , qrAlgorithm(EigenSparseQR) |
| | , autoChooseAlgorithm(true) |
| | , autoQRThreshold(1000) |
| | , dogLegGaussStep(FullPivLU) |
| | , qrpivotThreshold(1E-13) |
| | , debugMode(Minimal) |
| | , LM_eps(1E-10) |
| | , LM_eps1(1E-80) |
| | , LM_tau(1E-3) |
| | , DL_tolg(1E-80) |
| | , DL_tolx(1E-80) |
| | , DL_tolf(1E-10) |
| | , LM_epsRedundant(1E-10) |
| | , LM_eps1Redundant(1E-80) |
| | , LM_tauRedundant(1E-3) |
| | , DL_tolgRedundant(1E-80) |
| | , DL_tolxRedundant(1E-80) |
| | , DL_tolfRedundant(1E-10) |
| | { |
| | |
| | |
| | #ifdef EIGEN_SPARSEQR_COMPATIBLE |
| | Eigen::setNbThreads(1); |
| | #endif |
| | } |
| |
|
| | System::~System() |
| | { |
| | clear(); |
| | } |
| |
|
| | void System::clear() |
| | { |
| | plist.clear(); |
| | pdrivenlist.clear(); |
| | pIndex.clear(); |
| | pDependentParameters.clear(); |
| | pDependentParametersGroups.clear(); |
| | hasUnknowns = false; |
| | hasDiagnosis = false; |
| |
|
| | emptyDiagnoseMatrix = true; |
| |
|
| | redundant.clear(); |
| | conflictingTags.clear(); |
| | redundantTags.clear(); |
| | partiallyRedundantTags.clear(); |
| |
|
| | reference.clear(); |
| | clearSubSystems(); |
| | deleteAllContent(clist); |
| | c2p.clear(); |
| | p2c.clear(); |
| | } |
| |
|
| | void System::invalidatedDiagnosis() |
| | { |
| | hasDiagnosis = false; |
| | pDependentParameters.clear(); |
| | pDependentParametersGroups.clear(); |
| | } |
| |
|
| | void System::clearByTag(int tagId) |
| | { |
| | std::vector<Constraint*> constrvec; |
| | for (const auto& constr : clist) { |
| | if (constr->getTag() == tagId) { |
| | constrvec.push_back(constr); |
| | } |
| | } |
| | for (const auto& constr : constrvec) { |
| | removeConstraint(constr); |
| | } |
| | } |
| |
|
| | int System::addConstraint(Constraint* constr) |
| | { |
| | isInit = false; |
| | if (constr->getTag() >= 0) { |
| | hasDiagnosis = false; |
| | } |
| |
|
| | clist.push_back(constr); |
| | VEC_pD constr_params = constr->params(); |
| | for (const auto& param : constr_params) { |
| | |
| | c2p[constr].push_back(param); |
| | p2c[param].push_back(constr); |
| | } |
| | return clist.size() - 1; |
| | } |
| |
|
| | void System::removeConstraint(Constraint* constr) |
| | { |
| | std::vector<Constraint*>::iterator it; |
| | it = std::ranges::find(clist, constr); |
| | if (it == clist.end()) { |
| | return; |
| | } |
| |
|
| | clist.erase(it); |
| | if (constr->getTag() >= 0) { |
| | hasDiagnosis = false; |
| | } |
| | clearSubSystems(); |
| |
|
| | for (const auto& param : c2p[constr]) { |
| | p2c[param].erase(std::ranges::find(p2c[param], constr)); |
| | } |
| | c2p.erase(constr); |
| |
|
| | delete (constr); |
| | } |
| |
|
| | |
| |
|
| | int System::addConstraintEqual( |
| | double* param1, |
| | double* param2, |
| | int tagId, |
| | bool driving, |
| | Constraint::Alignment internalalignment |
| | ) |
| | { |
| | Constraint* constr = new ConstraintEqual(param1, param2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | constr->setInternalAlignment(internalalignment); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintProportional(double* param1, double* param2, double ratio, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintEqual(param1, param2, ratio); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintDifference(double* param1, double* param2, double* difference, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintDifference(param1, param2, difference); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintP2PDistance(Point& p1, Point& p2, double* distance, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintP2PDistance(p1, p2, distance); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintP2PAngle(Point& p1, Point& p2, double* angle, double incrAngle, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintP2PAngle(p1, p2, angle, incrAngle); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintP2PAngle(Point& p1, Point& p2, double* angle, int , bool driving) |
| | { |
| | return addConstraintP2PAngle(p1, p2, angle, 0., 0, driving); |
| | } |
| |
|
| | int System::addConstraintP2LDistance(Point& p, Line& l, double* distance, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintP2LDistance(p, l, distance); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPointOnLine(Point& p, Line& l, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnLine(p, l); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPointOnLine(Point& p, Point& lp1, Point& lp2, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnLine(p, lp1, lp2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPointOnPerpBisector(Point& p, Line& l, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnPerpBisector(p, l); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPointOnPerpBisector(Point& p, Point& lp1, Point& lp2, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnPerpBisector(p, lp1, lp2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintParallel(Line& l1, Line& l2, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintParallel(l1, l2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPerpendicular(Line& l1, Line& l2, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPerpendicular(l1, l2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPerpendicular( |
| | Point& l1p1, |
| | Point& l1p2, |
| | Point& l2p1, |
| | Point& l2p2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintPerpendicular(l1p1, l1p2, l2p1, l2p2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintL2LAngle(Line& l1, Line& l2, double* angle, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintL2LAngle(l1, l2, angle); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintL2LAngle( |
| | Point& l1p1, |
| | Point& l1p2, |
| | Point& l2p1, |
| | Point& l2p2, |
| | double* angle, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintL2LAngle(l1p1, l1p2, l2p1, l2p2, angle); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintAngleViaPoint(Curve& crv1, Curve& crv2, Point& p, double* angle, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintAngleViaPoint(crv1, crv2, p, angle); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintAngleViaTwoPoints( |
| | Curve& crv1, |
| | Curve& crv2, |
| | Point& p1, |
| | Point& p2, |
| | double* angle, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintAngleViaTwoPoints(crv1, crv2, p1, p2, angle); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintAngleViaPointAndParam( |
| | Curve& crv1, |
| | Curve& crv2, |
| | Point& p, |
| | double* cparam, |
| | double* angle, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintAngleViaPointAndParam(crv1, crv2, p, cparam, angle); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintAngleViaPointAndTwoParams( |
| | Curve& crv1, |
| | Curve& crv2, |
| | Point& p, |
| | double* cparam1, |
| | double* cparam2, |
| | double* angle, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr |
| | = new ConstraintAngleViaPointAndTwoParams(crv1, crv2, p, cparam1, cparam2, angle); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintMidpointOnLine(Line& l1, Line& l2, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintMidpointOnLine(l1, l2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintMidpointOnLine( |
| | Point& l1p1, |
| | Point& l1p2, |
| | Point& l2p1, |
| | Point& l2p2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintMidpointOnLine(l1p1, l1p2, l2p1, l2p2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintTangentCircumf( |
| | Point& p1, |
| | Point& p2, |
| | double* rad1, |
| | double* rad2, |
| | bool internal, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintTangentCircumf(p1, p2, rad1, rad2, internal); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintTangentAtBSplineKnot( |
| | BSpline& b, |
| | Line& l, |
| | unsigned int knotindex, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintSlopeAtBSplineKnot(b, l, knotindex); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintC2CDistance(Circle& c1, Circle& c2, double* dist, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintC2CDistance(c1, c2, dist); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintC2LDistance(Circle& c, Line& l, double* dist, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintC2LDistance(c, l, dist); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintP2CDistance(Point& p, Circle& c, double* distance, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintP2CDistance(p, c, distance); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintArcLength(Arc& a, double* distance, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintArcLength(a, distance); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| |
|
| | |
| |
|
| | int System::addConstraintP2PCoincident(Point& p1, Point& p2, int tagId, bool driving) |
| | { |
| | addConstraintEqual(p1.x, p2.x, tagId, driving); |
| | return addConstraintEqual(p1.y, p2.y, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintHorizontal(Line& l, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(l.p1.y, l.p2.y, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintHorizontal(Point& p1, Point& p2, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(p1.y, p2.y, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintVertical(Line& l, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(l.p1.x, l.p2.x, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintVertical(Point& p1, Point& p2, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(p1.x, p2.x, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintCoordinateX(Point& p, double* x, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(p.x, x, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintCoordinateY(Point& p, double* y, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(p.y, y, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintArcRules(Arc& a, int tagId, bool driving) |
| | { |
| | addConstraintCurveValue(a.start, a, a.startAngle, tagId, driving); |
| | return addConstraintCurveValue(a.end, a, a.endAngle, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintPointOnCircle(Point& p, Circle& c, int tagId, bool driving) |
| | { |
| | return addConstraintP2PDistance(p, c.center, c.rad, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintPointOnEllipse(Point& p, Ellipse& e, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnEllipse(p, e); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPointOnHyperbolicArc(Point& p, ArcOfHyperbola& e, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnHyperbola(p, e); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPointOnParabolicArc(Point& p, ArcOfParabola& e, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnParabola(p, e); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintPointOnBSpline(Point& p, BSpline& b, double* pointparam, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintPointOnBSpline(p.x, pointparam, 0, b); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | addConstraint(constr); |
| |
|
| | constr = new ConstraintPointOnBSpline(p.y, pointparam, 1, b); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintArcOfEllipseRules(ArcOfEllipse& a, int tagId, bool driving) |
| | { |
| | addConstraintCurveValue(a.start, a, a.startAngle, tagId, driving); |
| | return addConstraintCurveValue(a.end, a, a.endAngle, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintCurveValue(Point& p, Curve& a, double* u, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintCurveValue(p, p.x, a, u); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | addConstraint(constr); |
| | constr = new ConstraintCurveValue(p, p.y, a, u); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintArcOfHyperbolaRules(ArcOfHyperbola& a, int tagId, bool driving) |
| | { |
| | addConstraintCurveValue(a.start, a, a.startAngle, tagId, driving); |
| | return addConstraintCurveValue(a.end, a, a.endAngle, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintArcOfParabolaRules(ArcOfParabola& a, int tagId, bool driving) |
| | { |
| | addConstraintCurveValue(a.start, a, a.startAngle, tagId, driving); |
| | return addConstraintCurveValue(a.end, a, a.endAngle, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintPointOnArc(Point& p, Arc& a, int tagId, bool driving) |
| | { |
| | return addConstraintP2PDistance(p, a.center, a.rad, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintPerpendicularLine2Arc(Point& p1, Point& p2, Arc& a, int tagId, bool driving) |
| | { |
| | using std::numbers::pi; |
| |
|
| | addConstraintP2PCoincident(p2, a.start, tagId, driving); |
| | double dx = *(p2.x) - *(p1.x); |
| | double dy = *(p2.y) - *(p1.y); |
| | if (dx * cos(*(a.startAngle)) + dy * sin(*(a.startAngle)) > 0) { |
| | return addConstraintP2PAngle(p1, p2, a.startAngle, 0, tagId, driving); |
| | } |
| | else { |
| | return addConstraintP2PAngle(p1, p2, a.startAngle, pi, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintPerpendicularArc2Line(Arc& a, Point& p1, Point& p2, int tagId, bool driving) |
| | { |
| | using std::numbers::pi; |
| |
|
| | addConstraintP2PCoincident(p1, a.end, tagId, driving); |
| | double dx = *(p2.x) - *(p1.x); |
| | double dy = *(p2.y) - *(p1.y); |
| | if (dx * cos(*(a.endAngle)) + dy * sin(*(a.endAngle)) > 0) { |
| | return addConstraintP2PAngle(p1, p2, a.endAngle, 0, tagId, driving); |
| | } |
| | else { |
| | return addConstraintP2PAngle(p1, p2, a.endAngle, pi, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintPerpendicularCircle2Arc(Point& center, double* radius, Arc& a, int tagId, bool driving) |
| | { |
| | using std::numbers::pi; |
| |
|
| | addConstraintP2PDistance(a.start, center, radius, tagId, driving); |
| | double incrAngle = *(a.startAngle) < *(a.endAngle) ? pi / 2 : -pi / 2; |
| | double tangAngle = *a.startAngle + incrAngle; |
| | double dx = *(a.start.x) - *(center.x); |
| | double dy = *(a.start.y) - *(center.y); |
| | if (dx * cos(tangAngle) + dy * sin(tangAngle) > 0) { |
| | return addConstraintP2PAngle(center, a.start, a.startAngle, incrAngle, tagId, driving); |
| | } |
| | else { |
| | return addConstraintP2PAngle(center, a.start, a.startAngle, -incrAngle, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintPerpendicularArc2Circle(Arc& a, Point& center, double* radius, int tagId, bool driving) |
| | { |
| | using std::numbers::pi; |
| |
|
| | addConstraintP2PDistance(a.end, center, radius, tagId, driving); |
| | double incrAngle = *(a.startAngle) < *(a.endAngle) ? -pi / 2 : pi / 2; |
| | double tangAngle = *a.endAngle + incrAngle; |
| | double dx = *(a.end.x) - *(center.x); |
| | double dy = *(a.end.y) - *(center.y); |
| | if (dx * cos(tangAngle) + dy * sin(tangAngle) > 0) { |
| | return addConstraintP2PAngle(center, a.end, a.endAngle, incrAngle, tagId, driving); |
| | } |
| | else { |
| | return addConstraintP2PAngle(center, a.end, a.endAngle, -incrAngle, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintPerpendicularArc2Arc( |
| | Arc& a1, |
| | bool reverse1, |
| | Arc& a2, |
| | bool reverse2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Point& p1 = reverse1 ? a1.start : a1.end; |
| | Point& p2 = reverse2 ? a2.end : a2.start; |
| | addConstraintP2PCoincident(p1, p2, tagId, driving); |
| | return addConstraintPerpendicular(a1.center, p1, a2.center, p2, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintTangent(Line& l, Circle& c, int tagId, bool driving) |
| | { |
| | return addConstraintP2LDistance(c.center, l, c.rad, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintTangent(Line& l, Ellipse& e, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintEllipseTangentLine(l, e); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintTangent(Line& l, Arc& a, int tagId, bool driving) |
| | { |
| | return addConstraintP2LDistance(a.center, l, a.rad, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintTangent(Circle& c1, Circle& c2, int tagId, bool driving) |
| | { |
| | double dx = *(c2.center.x) - *(c1.center.x); |
| | double dy = *(c2.center.y) - *(c1.center.y); |
| | double d = sqrt(dx * dx + dy * dy); |
| | return addConstraintTangentCircumf( |
| | c1.center, |
| | c2.center, |
| | c1.rad, |
| | c2.rad, |
| | (d < *c1.rad || d < *c2.rad), |
| | tagId, |
| | driving |
| | ); |
| | } |
| |
|
| | int System::addConstraintTangent(Arc& a1, Arc& a2, int tagId, bool driving) |
| | { |
| | double dx = *(a2.center.x) - *(a1.center.x); |
| | double dy = *(a2.center.y) - *(a1.center.y); |
| | double d = sqrt(dx * dx + dy * dy); |
| | return addConstraintTangentCircumf( |
| | a1.center, |
| | a2.center, |
| | a1.rad, |
| | a2.rad, |
| | (d < *a1.rad || d < *a2.rad), |
| | tagId, |
| | driving |
| | ); |
| | } |
| |
|
| | int System::addConstraintTangent(Circle& c, Arc& a, int tagId, bool driving) |
| | { |
| | double dx = *(a.center.x) - *(c.center.x); |
| | double dy = *(a.center.y) - *(c.center.y); |
| | double d = sqrt(dx * dx + dy * dy); |
| | return addConstraintTangentCircumf( |
| | c.center, |
| | a.center, |
| | c.rad, |
| | a.rad, |
| | (d < *c.rad || d < *a.rad), |
| | tagId, |
| | driving |
| | ); |
| | } |
| |
|
| | int System::addConstraintCircleRadius(Circle& c, double* radius, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(c.rad, radius, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintArcRadius(Arc& a, double* radius, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(a.rad, radius, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintCircleDiameter(Circle& c, double* diameter, int tagId, bool driving) |
| | { |
| | return addConstraintProportional(c.rad, diameter, 0.5, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintArcDiameter(Arc& a, double* diameter, int tagId, bool driving) |
| | { |
| | return addConstraintProportional(a.rad, diameter, 0.5, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintEqualLength(Line& l1, Line& l2, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintEqualLineLength(l1, l2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintEqualRadius(Circle& c1, Circle& c2, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(c1.rad, c2.rad, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintEqualRadii(Ellipse& e1, Ellipse& e2, int tagId, bool driving) |
| | { |
| | addConstraintEqual(e1.radmin, e2.radmin, tagId, driving); |
| |
|
| | Constraint* constr = new ConstraintEqualMajorAxesConic(&e1, &e2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintEqualRadii(ArcOfHyperbola& a1, ArcOfHyperbola& a2, int tagId, bool driving) |
| | { |
| | addConstraintEqual(a1.radmin, a2.radmin, tagId, driving); |
| |
|
| | Constraint* constr = new ConstraintEqualMajorAxesConic(&a1, &a2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintEqualFocus(ArcOfParabola& a1, ArcOfParabola& a2, int tagId, bool driving) |
| | { |
| | Constraint* constr = new ConstraintEqualFocalDistance(&a1, &a2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintEqualRadius(Circle& c1, Arc& a2, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(c1.rad, a2.rad, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintEqualRadius(Arc& a1, Arc& a2, int tagId, bool driving) |
| | { |
| | return addConstraintEqual(a1.rad, a2.rad, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintP2PSymmetric(Point& p1, Point& p2, Line& l, int tagId, bool driving) |
| | { |
| | addConstraintPerpendicular(p1, p2, l.p1, l.p2, tagId, driving); |
| | return addConstraintMidpointOnLine(p1, p2, l.p1, l.p2, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintP2PSymmetric(Point& p1, Point& p2, Point& p, int tagId, bool driving) |
| | { |
| | addConstraintPointOnPerpBisector(p, p1, p2, tagId, driving); |
| | return addConstraintPointOnLine(p, p1, p2, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintSnellsLaw( |
| | Curve& ray1, |
| | Curve& ray2, |
| | Curve& boundary, |
| | Point p, |
| | double* n1, |
| | double* n2, |
| | bool flipn1, |
| | bool flipn2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintSnell(ray1, ray2, boundary, p, n1, n2, flipn1, flipn2); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentPoint2Ellipse( |
| | Ellipse& e, |
| | Point& p1, |
| | InternalAlignmentType alignmentType, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintInternalAlignmentPoint2Ellipse(e, p1, alignmentType); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | constr->setInternalAlignment(Constraint::Alignment::InternalAlignment); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentPoint2Hyperbola( |
| | Hyperbola& e, |
| | Point& p1, |
| | InternalAlignmentType alignmentType, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | Constraint* constr = new ConstraintInternalAlignmentPoint2Hyperbola(e, p1, alignmentType); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | constr->setInternalAlignment(Constraint::Alignment::InternalAlignment); |
| | return addConstraint(constr); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentEllipseMajorDiameter( |
| | Ellipse& e, |
| | Point& p1, |
| | Point& p2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | double X_1 = *p1.x; |
| | double Y_1 = *p1.y; |
| | double X_2 = *p2.x; |
| | double Y_2 = *p2.y; |
| | double X_c = *e.center.x; |
| | double Y_c = *e.center.y; |
| | double X_F1 = *e.focus1.x; |
| | double Y_F1 = *e.focus1.y; |
| | double b = *e.radmin; |
| |
|
| | double closertopositivemajor |
| | = pow(X_1 - X_c |
| | - (X_F1 - X_c) * sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | - pow(X_2 - X_c |
| | - (X_F1 - X_c) * sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | + pow(Y_1 - Y_c |
| | - (Y_F1 - Y_c) * sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | - pow(Y_2 - Y_c |
| | - (Y_F1 - Y_c) * sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2); |
| |
|
| | if (closertopositivemajor > 0) { |
| | |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMajorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMajorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseNegativeMajorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseNegativeMajorY, tagId, driving); |
| | } |
| | else { |
| | |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMajorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMajorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipseNegativeMajorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipseNegativeMajorY, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentEllipseMinorDiameter( |
| | Ellipse& e, |
| | Point& p1, |
| | Point& p2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | double X_1 = *p1.x; |
| | double Y_1 = *p1.y; |
| | double X_2 = *p2.x; |
| | double Y_2 = *p2.y; |
| | double X_c = *e.center.x; |
| | double Y_c = *e.center.y; |
| | double X_F1 = *e.focus1.x; |
| | double Y_F1 = *e.focus1.y; |
| | double b = *e.radmin; |
| |
|
| | double closertopositiveminor |
| | = pow(X_1 - X_c + b * (Y_F1 - Y_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) |
| | - pow(X_2 - X_c + b * (Y_F1 - Y_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) |
| | + pow(-Y_1 + Y_c + b * (X_F1 - X_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) |
| | - pow(-Y_2 + Y_c + b * (X_F1 - X_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2); |
| |
|
| | if (closertopositiveminor > 0) { |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMinorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMinorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseNegativeMinorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseNegativeMinorY, tagId, driving); |
| | } |
| | else { |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMinorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMinorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipseNegativeMinorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipseNegativeMinorY, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentEllipseFocus1(Ellipse& e, Point& p1, int tagId, bool driving) |
| | { |
| | addConstraintEqual(e.focus1.x, p1.x, tagId, driving, Constraint::Alignment::InternalAlignment); |
| | return addConstraintEqual(e.focus1.y, p1.y, tagId, driving, Constraint::Alignment::InternalAlignment); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentEllipseFocus2(Ellipse& e, Point& p1, int tagId, bool driving) |
| | { |
| | addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseFocus2X, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseFocus2Y, tagId, driving); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentHyperbolaMajorDiameter( |
| | Hyperbola& e, |
| | Point& p1, |
| | Point& p2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | double X_1 = *p1.x; |
| | double Y_1 = *p1.y; |
| | double X_2 = *p2.x; |
| | double Y_2 = *p2.y; |
| | double X_c = *e.center.x; |
| | double Y_c = *e.center.y; |
| | double X_F1 = *e.focus1.x; |
| | double Y_F1 = *e.focus1.y; |
| | double b = *e.radmin; |
| |
|
| | double closertopositivemajor = pow(-X_1 + X_c |
| | + (X_F1 - X_c) |
| | * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | - pow(-X_2 + X_c |
| | + (X_F1 - X_c) * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | + pow(-Y_1 + Y_c |
| | + (Y_F1 - Y_c) * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | - pow(-Y_2 + Y_c |
| | + (Y_F1 - Y_c) * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2); |
| |
|
| | if (closertopositivemajor > 0) { |
| | |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaPositiveMajorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaPositiveMajorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaNegativeMajorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaNegativeMajorY, tagId, driving); |
| | } |
| | else { |
| | |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaPositiveMajorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaPositiveMajorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaNegativeMajorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaNegativeMajorY, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentHyperbolaMinorDiameter( |
| | Hyperbola& e, |
| | Point& p1, |
| | Point& p2, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | double X_1 = *p1.x; |
| | double Y_1 = *p1.y; |
| | double X_2 = *p2.x; |
| | double Y_2 = *p2.y; |
| | double X_c = *e.center.x; |
| | double Y_c = *e.center.y; |
| | double X_F1 = *e.focus1.x; |
| | double Y_F1 = *e.focus1.y; |
| | double b = *e.radmin; |
| |
|
| | double closertopositiveminor |
| | = pow(-X_1 + X_c + b * (Y_F1 - Y_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | + (X_F1 - X_c) * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | - pow(-X_2 + X_c + b * (Y_F1 - Y_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | + (X_F1 - X_c) * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | + pow(-Y_1 + Y_c - b * (X_F1 - X_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | + (Y_F1 - Y_c) * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2) |
| | - pow(-Y_2 + Y_c - b * (X_F1 - X_c) / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | + (Y_F1 - Y_c) * (-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) |
| | / sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), |
| | 2); |
| |
|
| | if (closertopositiveminor < 0) { |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaPositiveMinorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaPositiveMinorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaNegativeMinorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaNegativeMinorY, tagId, driving); |
| | } |
| | else { |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaPositiveMinorX, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p1, HyperbolaPositiveMinorY, tagId, driving); |
| | addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaNegativeMinorX, tagId, driving); |
| | return addConstraintInternalAlignmentPoint2Hyperbola(e, p2, HyperbolaNegativeMinorY, tagId, driving); |
| | } |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentHyperbolaFocus(Hyperbola& e, Point& p1, int tagId, bool driving) |
| | { |
| | addConstraintEqual(e.focus1.x, p1.x, tagId, driving, Constraint::Alignment::InternalAlignment); |
| | return addConstraintEqual(e.focus1.y, p1.y, tagId, driving, Constraint::Alignment::InternalAlignment); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentParabolaFocus(Parabola& e, Point& p1, int tagId, bool driving) |
| | { |
| | addConstraintEqual(e.focus1.x, p1.x, tagId, driving, Constraint::Alignment::InternalAlignment); |
| | return addConstraintEqual(e.focus1.y, p1.y, tagId, driving, Constraint::Alignment::InternalAlignment); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentBSplineControlPoint( |
| | BSpline& b, |
| | Circle& c, |
| | unsigned int poleindex, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | addConstraintEqual( |
| | b.poles[poleindex].x, |
| | c.center.x, |
| | tagId, |
| | driving, |
| | Constraint::Alignment::InternalAlignment |
| | ); |
| | addConstraintEqual( |
| | b.poles[poleindex].y, |
| | c.center.y, |
| | tagId, |
| | driving, |
| | Constraint::Alignment::InternalAlignment |
| | ); |
| | return addConstraintEqual( |
| | b.weights[poleindex], |
| | c.rad, |
| | tagId, |
| | driving, |
| | Constraint::Alignment::InternalAlignment |
| | ); |
| | } |
| |
|
| | int System::addConstraintInternalAlignmentKnotPoint( |
| | BSpline& b, |
| | Point& p, |
| | unsigned int knotindex, |
| | int tagId, |
| | bool driving |
| | ) |
| | { |
| | if (b.periodic && knotindex == 0) { |
| | |
| | addConstraintP2PCoincident(p, b.start, tagId, driving); |
| | addConstraintP2PCoincident(p, b.end, tagId, driving); |
| | } |
| |
|
| | size_t numpoles = b.degree - b.mult[knotindex] + 1; |
| | if (numpoles == 0) { |
| | numpoles = 1; |
| | } |
| |
|
| | |
| | size_t startpole = 0; |
| | std::vector<double*> pvec; |
| | pvec.push_back(p.x); |
| |
|
| | std::vector<double> factors(numpoles, 1.0 / numpoles); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | for (size_t j = 1; j <= knotindex; ++j) { |
| | startpole += b.mult[j]; |
| | } |
| | |
| | |
| | |
| | |
| | if (!b.periodic && startpole >= b.poles.size()) { |
| | startpole = b.poles.size() - 1; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | if (numpoles > 1) { |
| | for (size_t i = 0; i < numpoles; ++i) { |
| | factors[i] = b.getLinCombFactor(*(b.knots[knotindex]), startpole + b.degree, startpole + i); |
| | } |
| | } |
| |
|
| | |
| | |
| | for (size_t i = 0; i < numpoles; ++i) { |
| | pvec.push_back(b.poles[(startpole + i) % b.poles.size()].x); |
| | } |
| | for (size_t i = 0; i < numpoles; ++i) { |
| | pvec.push_back(b.weights[(startpole + i) % b.poles.size()]); |
| | } |
| |
|
| | Constraint* constr = new ConstraintWeightedLinearCombination(numpoles, pvec, factors); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | constr->setInternalAlignment(Constraint::Alignment::InternalAlignment); |
| | addConstraint(constr); |
| |
|
| | pvec.clear(); |
| | pvec.push_back(p.y); |
| | for (size_t i = 0; i < numpoles; ++i) { |
| | pvec.push_back(b.poles[(startpole + i) % b.poles.size()].y); |
| | } |
| | for (size_t i = 0; i < numpoles; ++i) { |
| | pvec.push_back(b.weights[(startpole + i) % b.poles.size()]); |
| | } |
| |
|
| | constr = new ConstraintWeightedLinearCombination(numpoles, pvec, factors); |
| | constr->setTag(tagId); |
| | constr->setDriving(driving); |
| | constr->setInternalAlignment(Constraint::Alignment::InternalAlignment); |
| | return addConstraint(constr); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | double System::calculateAngleViaPoint(const Curve& crv1, const Curve& crv2, Point& p) const |
| | { |
| | return calculateAngleViaPoint(crv1, crv2, p, p); |
| | } |
| |
|
| | double System::calculateAngleViaPoint(const Curve& crv1, const Curve& crv2, Point& p1, Point& p2) const |
| | { |
| | GCS::DeriVector2 n1 = crv1.CalculateNormal(p1); |
| | GCS::DeriVector2 n2 = crv2.CalculateNormal(p2); |
| | return atan2(-n2.x * n1.y + n2.y * n1.x, n2.x * n1.x + n2.y * n1.y); |
| | } |
| |
|
| | double System::calculateAngleViaParams( |
| | const Curve& crv1, |
| | const Curve& crv2, |
| | double* param1, |
| | double* param2 |
| | ) const |
| | { |
| | GCS::DeriVector2 n1 = crv1.CalculateNormal(param1); |
| | GCS::DeriVector2 n2 = crv2.CalculateNormal(param2); |
| | return atan2(-n2.x * n1.y + n2.y * n1.x, n2.x * n1.x + n2.y * n1.y); |
| | } |
| |
|
| | void System::calculateNormalAtPoint(const Curve& crv, const Point& p, double& rtnX, double& rtnY) const |
| | { |
| | GCS::DeriVector2 n1 = crv.CalculateNormal(p); |
| | rtnX = n1.x; |
| | rtnY = n1.y; |
| | } |
| |
|
| | double System::calculateConstraintErrorByTag(int tagId) |
| | { |
| | int cnt = 0; |
| | double sqErr = 0.0; |
| | double err = 0.0; |
| |
|
| | for (const auto& constr : clist) { |
| | if (constr->getTag() == tagId) { |
| | err = constr->error(); |
| | sqErr += err * err; |
| | cnt++; |
| | }; |
| | } |
| | switch (cnt) { |
| | case 0: |
| | return std::numeric_limits<double>::quiet_NaN(); |
| | break; |
| | case 1: |
| | return err; |
| | break; |
| | default: |
| | return sqrt(sqErr / (double)cnt); |
| | } |
| | } |
| |
|
| | void System::rescaleConstraint(int id, double coeff) |
| | { |
| | if (id >= static_cast<int>(clist.size()) || id < 0) { |
| | return; |
| | } |
| | if (clist[id]) { |
| | clist[id]->rescale(coeff); |
| | } |
| | } |
| |
|
| | void System::declareUnknowns(VEC_pD& params) |
| | { |
| | plist = params; |
| | pIndex.clear(); |
| | for (int i = 0; i < int(plist.size()); ++i) { |
| | pIndex[plist[i]] = i; |
| | } |
| | hasUnknowns = true; |
| | } |
| |
|
| | void System::declareDrivenParams(VEC_pD& params) |
| | { |
| | pdrivenlist = params; |
| | } |
| |
|
| |
|
| | void System::initSolution(Algorithm alg) |
| | { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | isInit = false; |
| | if (!hasUnknowns) { |
| | return; |
| | } |
| |
|
| | |
| | setReference(); |
| |
|
| | |
| | if (!hasDiagnosis) { |
| | diagnose(alg); |
| | } |
| |
|
| | |
| | if (!hasDiagnosis) { |
| | return; |
| | } |
| |
|
| | std::vector<Constraint*> clistR; |
| | if (!redundant.empty()) { |
| | std::ranges::copy_if(clist, std::back_inserter(clistR), [this](auto constr) { |
| | return this->redundant.count(constr) == 0; |
| | }); |
| | } |
| | else { |
| | clistR = clist; |
| | } |
| |
|
| | |
| | Graph g; |
| | for (int i = 0; i < int(plist.size() + clistR.size()); i++) { |
| | boost::add_vertex(g); |
| | } |
| |
|
| | int cvtid = int(plist.size()); |
| | for (const auto constr : clistR) { |
| | VEC_pD& cparams = c2p[constr]; |
| | for (const auto param : cparams) { |
| | MAP_pD_I::const_iterator it = pIndex.find(param); |
| | if (it != pIndex.end()) { |
| | boost::add_edge(cvtid, it->second, g); |
| | } |
| | } |
| | ++cvtid; |
| | } |
| |
|
| | VEC_I components(boost::num_vertices(g)); |
| | int componentsSize = 0; |
| | if (!components.empty()) { |
| | componentsSize = boost::connected_components(g, &components[0]); |
| | } |
| |
|
| | |
| | std::set<Constraint*> reducedConstrs; |
| | reductionmaps.clear(); |
| | reductionmaps.resize(componentsSize); |
| | { |
| | VEC_pD reducedParams = plist; |
| |
|
| | for (const auto& constr : clistR) { |
| | if (!(constr->getTag() >= 0 && constr->getTypeId() == Equal)) { |
| | continue; |
| | } |
| | const auto it1 = pIndex.find(constr->params()[0]); |
| | const auto it2 = pIndex.find(constr->params()[1]); |
| | if (it1 == pIndex.end() || it2 == pIndex.end()) { |
| | continue; |
| | } |
| | reducedConstrs.insert(constr); |
| | double* p_kept = reducedParams[it1->second]; |
| | double* p_replaced = reducedParams[it2->second]; |
| | std::ranges::replace(reducedParams, p_replaced, p_kept); |
| | } |
| | for (size_t i = 0; i < plist.size(); ++i) { |
| | if (plist[i] != reducedParams[i]) { |
| | int cid = components[i]; |
| | reductionmaps[cid][plist[i]] = reducedParams[i]; |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | clists.clear(); |
| | clists.resize(componentsSize); |
| | size_t i = plist.size(); |
| | for (const auto& constr : clistR) { |
| | if (reducedConstrs.count(constr) == 0) { |
| | int cid = components[i]; |
| | clists[cid].push_back(constr); |
| | } |
| | ++i; |
| | } |
| |
|
| | plists.clear(); |
| | plists.resize(componentsSize); |
| | for (size_t i = 0; i < plist.size(); ++i) { |
| | int cid = components[i]; |
| | plists[cid].push_back(plist[i]); |
| | } |
| |
|
| | |
| | clearSubSystems(); |
| | subSystems.resize(clists.size(), nullptr); |
| | subSystemsAux.resize(clists.size(), nullptr); |
| | for (std::size_t cid = 0; cid < clists.size(); ++cid) { |
| | std::vector<Constraint*> clist0, clist1; |
| | std::ranges::partition_copy( |
| | clists[cid], |
| | std::back_inserter(clist0), |
| | std::back_inserter(clist1), |
| | [](auto constr) { return constr->getTag() >= 0 && constr->isDriving(); } |
| | ); |
| |
|
| | if (!clist0.empty()) { |
| | subSystems[cid] = new SubSystem(clist0, plists[cid], reductionmaps[cid]); |
| | } |
| | if (!clist1.empty()) { |
| | subSystemsAux[cid] = new SubSystem(clist1, plists[cid], reductionmaps[cid]); |
| | } |
| | } |
| |
|
| | isInit = true; |
| | } |
| |
|
| | void System::setReference() |
| | { |
| | reference.clear(); |
| | reference.reserve(plist.size()); |
| | for (const auto& param : plist) { |
| | reference.push_back(*param); |
| | } |
| | } |
| |
|
| | void System::resetToReference() |
| | { |
| | if (reference.size() == plist.size()) { |
| | VEC_D::const_iterator ref = reference.begin(); |
| | VEC_pD::iterator param = plist.begin(); |
| | for (; ref != reference.end(); ++ref, ++param) { |
| | **param = *ref; |
| | } |
| | } |
| | } |
| |
|
| | int System::solve(VEC_pD& params, bool isFine, Algorithm alg, bool isRedundantsolving) |
| | { |
| | declareUnknowns(params); |
| | initSolution(); |
| | return solve(isFine, alg, isRedundantsolving); |
| | } |
| |
|
| | int System::solve(bool isFine, Algorithm alg, bool isRedundantsolving) |
| | { |
| | if (!isInit) { |
| | return Failed; |
| | } |
| |
|
| | bool isReset = false; |
| | |
| | |
| | int res = Success; |
| | for (int cid = 0; cid < int(subSystems.size()); cid++) { |
| | if ((subSystems[cid] || subSystemsAux[cid]) && !isReset) { |
| | resetToReference(); |
| | isReset = true; |
| | } |
| | if (subSystems[cid] && subSystemsAux[cid]) { |
| | res = std::max(res, solve(subSystems[cid], subSystemsAux[cid], isFine, isRedundantsolving)); |
| | } |
| | else if (subSystems[cid]) { |
| | res = std::max(res, solve(subSystems[cid], isFine, alg, isRedundantsolving)); |
| | } |
| | else if (subSystemsAux[cid]) { |
| | res = std::max(res, solve(subSystemsAux[cid], isFine, alg, isRedundantsolving)); |
| | } |
| | } |
| | if (res == Success) { |
| | for (std::set<Constraint*>::const_iterator constr = redundant.begin(); |
| | constr != redundant.end(); |
| | ++constr) { |
| | |
| | |
| | |
| | double err = (*constr)->error(); |
| | if (err * err > (isRedundantsolving ? convergenceRedundant : convergence)) { |
| | res = Converged; |
| | return res; |
| | } |
| | } |
| | } |
| | return res; |
| | } |
| |
|
| | int System::solve(SubSystem* subsys, bool isFine, Algorithm alg, bool isRedundantsolving) |
| | { |
| | if (alg == BFGS) { |
| | return solve_BFGS(subsys, isFine, isRedundantsolving); |
| | } |
| | else if (alg == LevenbergMarquardt) { |
| | return solve_LM(subsys, isRedundantsolving); |
| | } |
| | else if (alg == DogLeg) { |
| | return solve_DL(subsys, isRedundantsolving); |
| | } |
| | else { |
| | return Failed; |
| | } |
| | } |
| |
|
| | int System::solve_BFGS(SubSystem* subsys, bool , bool isRedundantsolving) |
| | { |
| | #ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_ |
| | extractSubsystem(subsys, isRedundantsolving); |
| | #endif |
| |
|
| | int xsize = subsys->pSize(); |
| | if (xsize == 0) { |
| | return Success; |
| | } |
| |
|
| | subsys->redirectParams(); |
| |
|
| | Eigen::MatrixXd D = Eigen::MatrixXd::Identity(xsize, xsize); |
| | Eigen::VectorXd x(xsize); |
| | Eigen::VectorXd xdir(xsize); |
| | Eigen::VectorXd grad(xsize); |
| | Eigen::VectorXd h(xsize); |
| | Eigen::VectorXd y(xsize); |
| | Eigen::VectorXd Dy(xsize); |
| |
|
| | |
| | subsys->getParams(x); |
| | subsys->calcGrad(grad); |
| |
|
| | |
| | xdir = -grad; |
| | lineSearch(subsys, xdir); |
| | double err = subsys->error(); |
| |
|
| | h = x; |
| | subsys->getParams(x); |
| | h = x - h; |
| |
|
| | |
| | int maxIterNumber = (sketchSizeMultiplier ? maxIter * xsize : maxIter); |
| | double convCriterion = convergence; |
| | if (isRedundantsolving) { |
| | maxIterNumber = (sketchSizeMultiplierRedundant ? maxIterRedundant * xsize : maxIterRedundant); |
| | convCriterion = convergenceRedundant; |
| | } |
| |
|
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | stream << "BFGS: convergence: " << convCriterion << ", xsize: " << xsize |
| | << ", maxIter: " << maxIterNumber << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| |
|
| | double divergingLim = 1e6 * err + 1e12; |
| | double h_norm {}; |
| |
|
| | for (int iter = 1; iter < maxIterNumber; ++iter) { |
| | h_norm = h.norm(); |
| | if (h_norm <= convCriterion || err <= smallF) { |
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | stream << "BFGS Converged!!: " |
| | << ", err: " << err << ", h_norm: " << h_norm << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| | break; |
| | } |
| | if (err > divergingLim || err != err) { |
| | |
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | stream << "BFGS Failed: Diverging!!: " |
| | << ", err: " << err << ", divergingLim: " << divergingLim << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| | break; |
| | } |
| |
|
| | y = grad; |
| | subsys->calcGrad(grad); |
| | y = grad - y; |
| |
|
| | double hty = h.dot(y); |
| | |
| | if (hty == 0) { |
| | hty = .0000000001; |
| | } |
| |
|
| | Dy = D * y; |
| |
|
| | double ytDy = y.dot(Dy); |
| |
|
| | |
| | D += (1. + ytDy / hty) / hty * h * h.transpose(); |
| | D -= 1. / hty * (h * Dy.transpose() + Dy * h.transpose()); |
| |
|
| | xdir = -D * grad; |
| | lineSearch(subsys, xdir); |
| | err = subsys->error(); |
| |
|
| | h = x; |
| | subsys->getParams(x); |
| | h = x - h; |
| |
|
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | stream << "BFGS, Iteration: " << iter << ", err: " << err << ", h_norm: " << h_norm |
| | << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| | } |
| |
|
| | subsys->revertParams(); |
| |
|
| | if (err <= smallF) { |
| | return Success; |
| | } |
| | if (h.norm() <= convCriterion) { |
| | return Converged; |
| | } |
| | return Failed; |
| | } |
| |
|
| | int System::solve_LM(SubSystem* subsys, bool isRedundantsolving) |
| | { |
| | #ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_ |
| | extractSubsystem(subsys, isRedundantsolving); |
| | #endif |
| |
|
| | int xsize = subsys->pSize(); |
| | int csize = subsys->cSize(); |
| |
|
| | if (xsize == 0) { |
| | return Success; |
| | } |
| |
|
| | Eigen::VectorXd e(csize), |
| | e_new(csize); |
| | Eigen::MatrixXd J(csize, xsize); |
| | Eigen::MatrixXd A(xsize, xsize); |
| | Eigen::VectorXd x(xsize), h(xsize), x_new(xsize), g(xsize), diag_A(xsize); |
| |
|
| | subsys->redirectParams(); |
| |
|
| | subsys->getParams(x); |
| | subsys->calcResidual(e); |
| | e *= -1; |
| |
|
| | int maxIterNumber = (sketchSizeMultiplier ? maxIter * xsize : maxIter); |
| |
|
| | double divergingLim = 1e6 * e.squaredNorm() + 1e12; |
| |
|
| | double eps = LM_eps; |
| | double eps1 = LM_eps1; |
| | double tau = LM_tau; |
| |
|
| | if (isRedundantsolving) { |
| | maxIterNumber = (sketchSizeMultiplierRedundant ? maxIterRedundant * xsize : maxIterRedundant); |
| | eps = LM_epsRedundant; |
| | eps1 = LM_eps1Redundant; |
| | tau = LM_tauRedundant; |
| | } |
| |
|
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | stream << "LM: eps: " << eps << ", eps1: " << eps1 << ", tau: " << tau |
| | << ", convergence: " << (isRedundantsolving ? convergenceRedundant : convergence) |
| | << ", xsize: " << xsize << ", maxIter: " << maxIterNumber << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| |
|
| | double nu = 2, mu = 0; |
| | int iter = 0, stop = 0; |
| | for (iter = 0; iter < maxIterNumber && !stop; ++iter) { |
| | |
| | double err = e.squaredNorm(); |
| | if (err <= eps * eps) { |
| | |
| | stop = 1; |
| | break; |
| | } |
| | else if (err > divergingLim || err != err) { |
| | |
| | stop = 6; |
| | break; |
| | } |
| |
|
| | |
| | subsys->calcJacobi(J); |
| |
|
| | A = J.transpose() * J; |
| | g = J.transpose() * e; |
| |
|
| | |
| | double g_inf = g.lpNorm<Eigen::Infinity>(); |
| | diag_A = A.diagonal(); |
| |
|
| | |
| | if (g_inf <= eps1) { |
| | stop = 2; |
| | break; |
| | } |
| |
|
| | |
| | if (iter == 0) { |
| | mu = tau * diag_A.lpNorm<Eigen::Infinity>(); |
| | } |
| |
|
| | double h_norm {}; |
| | |
| | int k = 0; |
| | while (k < 50) { |
| | |
| | for (int i = 0; i < xsize; ++i) { |
| | A(i, i) += mu; |
| | } |
| |
|
| | |
| | h = A.fullPivLu().solve(g); |
| | double rel_error = (A * h - g).norm() / g.norm(); |
| |
|
| | |
| | if (rel_error < 1e-5) { |
| | |
| | double scale = subsys->maxStep(h); |
| | if (scale < 1.) { |
| | h *= scale; |
| | } |
| |
|
| | |
| | x_new = x + h; |
| | h_norm = h.squaredNorm(); |
| |
|
| | constexpr double epsilon = std::numeric_limits<double>::epsilon(); |
| | if (h_norm <= eps1 * eps1 * x.norm()) { |
| | |
| | stop = 3; |
| | break; |
| | } |
| | else if (h_norm >= (x.norm() + eps1) / (epsilon * epsilon)) { |
| | |
| | stop = 4; |
| | break; |
| | } |
| |
|
| | subsys->setParams(x_new); |
| | subsys->calcResidual(e_new); |
| | e_new *= -1; |
| |
|
| | double dF = e.squaredNorm() - e_new.squaredNorm(); |
| | double dL = h.dot(mu * h + g); |
| |
|
| | if (dF > 0. && dL > 0.) { |
| | double tmp = 2 * dF / dL - 1.; |
| | mu *= std::max(1. / 3., 1. - tmp * tmp * tmp); |
| | nu = 2; |
| |
|
| | |
| | x = x_new; |
| | e = e_new; |
| | break; |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | mu *= nu; |
| | nu *= 2.0; |
| | for (int i = 0; i < xsize; ++i) { |
| | A(i, i) = diag_A(i); |
| | } |
| |
|
| | k++; |
| | } |
| | if (k > 50) { |
| | stop = 7; |
| | break; |
| | } |
| |
|
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | |
| | stream << "LM, Iteration: " << iter << ", err(eps): " << err |
| | << ", g_inf(eps1): " << g_inf << ", h_norm: " << h_norm << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| | } |
| |
|
| | if (iter >= maxIterNumber) { |
| | stop = 5; |
| | } |
| |
|
| | subsys->revertParams(); |
| |
|
| | return (stop == 1) ? Success : Failed; |
| | } |
| |
|
| | int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) |
| | { |
| | #ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_ |
| | extractSubsystem(subsys, isRedundantsolving); |
| | #endif |
| |
|
| | int xsize = subsys->pSize(); |
| | int csize = subsys->cSize(); |
| |
|
| | if (xsize == 0) { |
| | return Success; |
| | } |
| |
|
| | double tolg = DL_tolg; |
| | double tolx = DL_tolx; |
| | double tolf = DL_tolf; |
| |
|
| | int maxIterNumber = (sketchSizeMultiplier ? maxIter * xsize : maxIter); |
| | if (isRedundantsolving) { |
| | tolg = DL_tolgRedundant; |
| | tolx = DL_tolxRedundant; |
| | tolf = DL_tolfRedundant; |
| |
|
| | maxIterNumber = (sketchSizeMultiplierRedundant ? maxIterRedundant * xsize : maxIterRedundant); |
| | } |
| |
|
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | stream << "DL: tolg: " << tolg << ", tolx: " << tolx << ", tolf: " << tolf |
| | << ", convergence: " << (isRedundantsolving ? convergenceRedundant : convergence) |
| | << ", dogLegGaussStep: " |
| | << (dogLegGaussStep == FullPivLU |
| | ? "FullPivLU" |
| | : (dogLegGaussStep == LeastNormFullPivLU ? "LeastNormFullPivLU" |
| | : "LeastNormLdlt")) |
| | << ", xsize: " << xsize << ", csize: " << csize << ", maxIter: " << maxIterNumber |
| | << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| |
|
| | Eigen::VectorXd x(xsize), x_new(xsize); |
| | Eigen::VectorXd fx(csize), fx_new(csize); |
| | Eigen::MatrixXd Jx(csize, xsize), Jx_new(csize, xsize); |
| | Eigen::VectorXd g(xsize), h_sd(xsize), h_gn(xsize), h_dl(xsize); |
| |
|
| | subsys->redirectParams(); |
| |
|
| | double err; |
| | subsys->getParams(x); |
| | subsys->calcResidual(fx, err); |
| | subsys->calcJacobi(Jx); |
| |
|
| | g = Jx.transpose() * (-fx); |
| |
|
| | |
| | double g_inf = g.lpNorm<Eigen::Infinity>(); |
| | double fx_inf = fx.lpNorm<Eigen::Infinity>(); |
| |
|
| | double divergingLim = 1e6 * err + 1e12; |
| |
|
| | double delta = 0.1; |
| | double alpha = 0.; |
| | double nu = 2.; |
| | int iter = 0, stop = 0, reduce = 0; |
| | while (!stop) { |
| | |
| | if (fx_inf <= tolf) { |
| | |
| | stop = 1; |
| | break; |
| | } |
| | else if (g_inf <= tolg) { |
| | stop = 2; |
| | break; |
| | } |
| | else if (delta <= tolx * (tolx + x.norm())) { |
| | stop = 2; |
| | break; |
| | } |
| | else if (iter >= maxIterNumber) { |
| | stop = 4; |
| | break; |
| | } |
| | else if (err > divergingLim || err != err) { |
| | |
| | stop = 6; |
| | break; |
| | } |
| |
|
| | |
| | alpha = g.squaredNorm() / (Jx * g).squaredNorm(); |
| | h_sd = alpha * g; |
| |
|
| | |
| | |
| | |
| | switch (dogLegGaussStep) { |
| | case FullPivLU: |
| | h_gn = Jx.fullPivLu().solve(-fx); |
| | break; |
| | case LeastNormFullPivLU: |
| | h_gn = Jx.adjoint() * (Jx * Jx.adjoint()).fullPivLu().solve(-fx); |
| | break; |
| | case LeastNormLdlt: |
| | h_gn = Jx.adjoint() * (Jx * Jx.adjoint()).ldlt().solve(-fx); |
| | break; |
| | } |
| |
|
| | double rel_error = (Jx * h_gn + fx).norm() / fx.norm(); |
| | if (rel_error > 1e15) { |
| | break; |
| | } |
| |
|
| | |
| | if (h_gn.norm() < delta) { |
| | h_dl = h_gn; |
| | if (h_dl.norm() <= tolx * (tolx + x.norm())) { |
| | stop = 5; |
| | break; |
| | } |
| | } |
| | else if (alpha * g.norm() >= delta) { |
| | h_dl = (delta / (alpha * g.norm())) * h_sd; |
| | } |
| | else { |
| | |
| | double beta = 0; |
| | Eigen::VectorXd b = h_gn - h_sd; |
| | double bb = (b.transpose() * b).norm(); |
| | double gb = (h_sd.transpose() * b).norm(); |
| | double c = (delta + h_sd.norm()) * (delta - h_sd.norm()); |
| |
|
| | if (gb > 0) { |
| | beta = c / (gb + sqrt(gb * gb + c * bb)); |
| | } |
| | else { |
| | beta = (sqrt(gb * gb + c * bb) - gb) / bb; |
| | } |
| |
|
| | |
| | h_dl = h_sd + beta * b; |
| | } |
| |
|
| | |
| | double err_new; |
| | x_new = x + h_dl; |
| | subsys->setParams(x_new); |
| | subsys->calcResidual(fx_new, err_new); |
| | subsys->calcJacobi(Jx_new); |
| |
|
| | |
| | double dL = err - 0.5 * (fx + Jx * h_dl).squaredNorm(); |
| | double dF = err - err_new; |
| | double rho = dL / dF; |
| |
|
| | if (dF > 0 && dL > 0) { |
| | x = x_new; |
| | Jx = Jx_new; |
| | fx = fx_new; |
| | err = err_new; |
| |
|
| | g = Jx.transpose() * (-fx); |
| |
|
| | |
| | g_inf = g.lpNorm<Eigen::Infinity>(); |
| | fx_inf = fx.lpNorm<Eigen::Infinity>(); |
| | } |
| | else { |
| | rho = -1; |
| | } |
| |
|
| | |
| | if (fabs(rho - 1.) < 0.2 && h_dl.norm() > delta / 3. && reduce <= 0) { |
| | delta = 3 * delta; |
| | nu = 2; |
| | reduce = 0; |
| | } |
| | else if (rho < 0.25) { |
| | delta = delta / nu; |
| | nu = 2 * nu; |
| | reduce = 2; |
| | } |
| | else { |
| | reduce--; |
| | } |
| |
|
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | |
| | stream << "DL, Iteration: " << iter << ", fx_inf(tolf): " << fx_inf |
| | << ", g_inf(tolg): " << g_inf << ", delta(f(tolx)): " << delta |
| | << ", err(divergingLim): " << err << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| |
|
| | |
| | iter++; |
| | } |
| |
|
| | subsys->revertParams(); |
| |
|
| | if (debugMode == IterationLevel) { |
| | std::stringstream stream; |
| | stream << "DL: stopcode: " << stop << ((stop == 1) ? ", Success" : ", Failed") << "\n"; |
| |
|
| | const std::string tmp = stream.str(); |
| | Base::Console().log(tmp.c_str()); |
| | } |
| |
|
| | return (stop == 1) ? Success : Failed; |
| | } |
| |
|
| | #ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_ |
| | void System::extractSubsystem(SubSystem* subsys, bool isRedundantsolving) |
| | { |
| | VEC_pD plistout; |
| | std::vector<Constraint*> clist_; |
| | VEC_pD clist_params_; |
| |
|
| | subsys->getParamList(plistout); |
| | subsys->getConstraintList(clist_); |
| |
|
| | std::ofstream subsystemfile; |
| | subsystemfile.open("subsystemfile.txt", std::ofstream::out | std::ofstream::app); |
| | subsystemfile << std::endl; |
| | subsystemfile << std::endl; |
| | subsystemfile << "Solving: " << (isRedundantsolving ? "Redundant" : "Normal") |
| | << " Subsystem Dump starts here................................" << std::endl; |
| |
|
| | int ip = 0; |
| |
|
| | subsystemfile << "GCS::VEC_pD plist_;" << std::endl; |
| | subsystemfile << "std::vector<GCS::Constraint *> clist_;" << std::endl; |
| | subsystemfile << "GCS::VEC_pD plistsub_;" << std::endl; |
| | |
| | subsystemfile << "GCS::VEC_pD clist_params_;" << std::endl; |
| |
|
| | |
| | |
| | for (VEC_pD::iterator it = plist.begin(); it != plist.end(); ++it, ++ip) { |
| | subsystemfile << "plist_.push_back(new double(" << *(*it) << ")); // " << ip |
| | << " address: " << (void*)(*it) << std::endl; |
| | } |
| |
|
| | int ips = 0; |
| | for (VEC_pD::iterator it = plistout.begin(); it != plistout.end(); ++it, ++ips) { |
| | VEC_pD::iterator p = std::ranges::find(plist, (*it)); |
| | size_t p_index = std::distance(plist.begin(), p); |
| |
|
| | if (p_index == plist.size()) { |
| | subsystemfile << "// Error: Subsystem parameter not in system params" |
| | << "address: " << (void*)(*it) << std::endl; |
| | } |
| |
|
| | subsystemfile << "plistsub_.push_back(plist_[" << p_index << "]); // " << ips << std::endl; |
| | } |
| |
|
| | int ic = 0; |
| | int icp = 0; |
| | for (std::vector<Constraint*>::iterator it = clist_.begin(); it != clist_.end(); ++it, ++ic) { |
| |
|
| | switch ((*it)->getTypeId()) { |
| | case Equal: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | subsystemfile << "clist_.push_back(new ConstraintEqual(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]," << (npb2 ? ("clist_params_[") : ("plist_[")) |
| | << (npb2 ? ni2 : i2) << "])); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << std::endl; |
| | break; |
| | } |
| | case Difference: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | subsystemfile << "clist_.push_back(new ConstraintDifference(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]," << (npb2 ? ("clist_params_[") : ("plist_[")) |
| | << (npb2 ? ni2 : i2) << "]," |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "])); // addresses = " << (*it)->pvec[0] << "," << (*it)->pvec[1] |
| | << "," << (*it)->pvec[2] << std::endl; |
| | break; |
| | } |
| | case P2PDistance: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintP2PDistance * c" << ic |
| | << "=new ConstraintP2PDistance();" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic << "); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << "," << (*it)->pvec[2] << "," |
| | << (*it)->pvec[3] << "," << (*it)->pvec[4] << std::endl; |
| | break; |
| | } |
| | case P2PAngle: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintP2PAngle * c" << ic << "=new ConstraintP2PAngle();" |
| | << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic << "); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << "," << (*it)->pvec[2] << "," |
| | << (*it)->pvec[3] << "," << (*it)->pvec[4] << std::endl; |
| | break; |
| | } |
| | case P2LDistance: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | VEC_pD::iterator p7 = std::ranges::find(plist, (*it)->pvec[6]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| | size_t i7 = std::distance(plist.begin(), p7); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | bool npb7 = false; |
| | VEC_pD::iterator np7 = std::ranges::find(clist_params_, (*it)->pvec[6]); |
| | size_t ni7 = std::distance(clist_params_.begin(), np7); |
| |
|
| | if (i7 == plist.size()) { |
| | if (ni7 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[6]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[6]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[6] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb7 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintP2LDistance * c" << ic |
| | << "=new ConstraintP2LDistance();" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb7 ? ("clist_params_[") : ("plist_[")) << (npb7 ? ni7 : i7) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic << "); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << "," << (*it)->pvec[2] << "," |
| | << (*it)->pvec[3] << "," << (*it)->pvec[4] << "," << (*it)->pvec[5] |
| | << "," << (*it)->pvec[6] << std::endl; |
| | break; |
| | } |
| | case PointOnLine: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintPointOnLine * c" << ic |
| | << "=new ConstraintPointOnLine();" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic |
| | << "); // addresses = " << (*it)->pvec[0] << "," << (*it)->pvec[1] |
| | << "," << (*it)->pvec[2] << "," << (*it)->pvec[3] << "," |
| | << (*it)->pvec[4] << "," << (*it)->pvec[5] << std::endl; |
| | break; |
| | } |
| | case PointOnPerpBisector: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintPointOnPerpBisector * c" << ic |
| | << "=new ConstraintPointOnPerpBisector();" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic |
| | << "); // addresses = " << (*it)->pvec[0] << "," << (*it)->pvec[1] |
| | << "," << (*it)->pvec[2] << "," << (*it)->pvec[3] << "," |
| | << (*it)->pvec[4] << "," << (*it)->pvec[5] << std::endl; |
| | break; |
| | } |
| | case Parallel: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | VEC_pD::iterator p7 = std::ranges::find(plist, (*it)->pvec[6]); |
| | VEC_pD::iterator p8 = std::ranges::find(plist, (*it)->pvec[7]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| | size_t i7 = std::distance(plist.begin(), p7); |
| | size_t i8 = std::distance(plist.begin(), p8); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | bool npb7 = false; |
| | VEC_pD::iterator np7 = std::ranges::find(clist_params_, (*it)->pvec[6]); |
| | size_t ni7 = std::distance(clist_params_.begin(), np7); |
| |
|
| | if (i7 == plist.size()) { |
| | if (ni7 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[6]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[6]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[6] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb7 = true; |
| | } |
| |
|
| | bool npb8 = false; |
| | VEC_pD::iterator np8 = std::ranges::find(clist_params_, (*it)->pvec[7]); |
| | size_t ni8 = std::distance(clist_params_.begin(), np8); |
| |
|
| | if (i8 == plist.size()) { |
| | if (ni8 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[7]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[7]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[7] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb8 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintParallel * c" << ic << "=new ConstraintParallel();" |
| | << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb7 ? ("clist_params_[") : ("plist_[")) << (npb7 ? ni7 : i7) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb8 ? ("clist_params_[") : ("plist_[")) << (npb8 ? ni8 : i8) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic << "); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << "," << (*it)->pvec[2] << "," |
| | << (*it)->pvec[3] << "," << (*it)->pvec[4] << "," << (*it)->pvec[5] |
| | << "," << (*it)->pvec[6] << "," << (*it)->pvec[7] << std::endl; |
| | break; |
| | } |
| | case Perpendicular: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | VEC_pD::iterator p7 = std::ranges::find(plist, (*it)->pvec[6]); |
| | VEC_pD::iterator p8 = std::ranges::find(plist, (*it)->pvec[7]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| | size_t i7 = std::distance(plist.begin(), p7); |
| | size_t i8 = std::distance(plist.begin(), p8); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | bool npb7 = false; |
| | VEC_pD::iterator np7 = std::ranges::find(clist_params_, (*it)->pvec[6]); |
| | size_t ni7 = std::distance(clist_params_.begin(), np7); |
| |
|
| | if (i7 == plist.size()) { |
| | if (ni7 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[6]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[6]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[6] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb7 = true; |
| | } |
| |
|
| | bool npb8 = false; |
| | VEC_pD::iterator np8 = std::ranges::find(clist_params_, (*it)->pvec[7]); |
| | size_t ni8 = std::distance(clist_params_.begin(), np8); |
| |
|
| | if (i8 == plist.size()) { |
| | if (ni8 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[7]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[7]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[7] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb8 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintPerpendicular * c" << ic |
| | << "=new ConstraintPerpendicular();" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb7 ? ("clist_params_[") : ("plist_[")) << (npb7 ? ni7 : i7) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb8 ? ("clist_params_[") : ("plist_[")) << (npb8 ? ni8 : i8) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic << "); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << "," << (*it)->pvec[2] << "," |
| | << (*it)->pvec[3] << "," << (*it)->pvec[4] << "," << (*it)->pvec[5] |
| | << "," << (*it)->pvec[6] << "," << (*it)->pvec[7] << std::endl; |
| | break; |
| | } |
| | case L2LAngle: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | VEC_pD::iterator p7 = std::ranges::find(plist, (*it)->pvec[6]); |
| | VEC_pD::iterator p8 = std::ranges::find(plist, (*it)->pvec[7]); |
| | VEC_pD::iterator p9 = std::ranges::find(plist, (*it)->pvec[8]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| | size_t i7 = std::distance(plist.begin(), p7); |
| | size_t i8 = std::distance(plist.begin(), p8); |
| | size_t i9 = std::distance(plist.begin(), p9); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | bool npb7 = false; |
| | VEC_pD::iterator np7 = std::ranges::find(clist_params_, (*it)->pvec[6]); |
| | size_t ni7 = std::distance(clist_params_.begin(), np7); |
| |
|
| | if (i7 == plist.size()) { |
| | if (ni7 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[6]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[6]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[6] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb7 = true; |
| | } |
| |
|
| | bool npb8 = false; |
| | VEC_pD::iterator np8 = std::ranges::find(clist_params_, (*it)->pvec[7]); |
| | size_t ni8 = std::distance(clist_params_.begin(), np8); |
| |
|
| | if (i8 == plist.size()) { |
| | if (ni8 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[7]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[7]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[7] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb8 = true; |
| | } |
| |
|
| | bool npb9 = false; |
| | VEC_pD::iterator np9 = std::ranges::find(clist_params_, (*it)->pvec[8]); |
| | size_t ni9 = std::distance(clist_params_.begin(), np9); |
| |
|
| | if (i9 == plist.size()) { |
| | if (ni9 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[8]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[8]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[8] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb9 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintL2LAngle * c" << ic << "=new ConstraintL2LAngle();" |
| | << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb7 ? ("clist_params_[") : ("plist_[")) << (npb7 ? ni7 : i7) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb8 ? ("clist_params_[") : ("plist_[")) << (npb8 ? ni8 : i8) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb9 ? ("clist_params_[") : ("plist_[")) << (npb9 ? ni9 : i9) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic |
| | << "); // addresses = " << (*it)->pvec[0] << "," << (*it)->pvec[1] |
| | << "," << (*it)->pvec[2] << "," << (*it)->pvec[3] << "," |
| | << (*it)->pvec[4] << "," << (*it)->pvec[5] << "," << (*it)->pvec[6] |
| | << "," << (*it)->pvec[7] << "," << (*it)->pvec[8] << std::endl; |
| | break; |
| | } |
| | case MidpointOnLine: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | VEC_pD::iterator p7 = std::ranges::find(plist, (*it)->pvec[6]); |
| | VEC_pD::iterator p8 = std::ranges::find(plist, (*it)->pvec[7]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| | size_t i7 = std::distance(plist.begin(), p7); |
| | size_t i8 = std::distance(plist.begin(), p8); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | bool npb7 = false; |
| | VEC_pD::iterator np7 = std::ranges::find(clist_params_, (*it)->pvec[6]); |
| | size_t ni7 = std::distance(clist_params_.begin(), np7); |
| |
|
| | if (i7 == plist.size()) { |
| | if (ni7 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[6]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[6]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[6] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb7 = true; |
| | } |
| |
|
| | bool npb8 = false; |
| | VEC_pD::iterator np8 = std::ranges::find(clist_params_, (*it)->pvec[7]); |
| | size_t ni8 = std::distance(clist_params_.begin(), np8); |
| |
|
| | if (i8 == plist.size()) { |
| | if (ni8 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[7]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[7]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[7] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb8 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintMidpointOnLine * c" << ic |
| | << "=new ConstraintMidpointOnLine();" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb7 ? ("clist_params_[") : ("plist_[")) << (npb7 ? ni7 : i7) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb8 ? ("clist_params_[") : ("plist_[")) << (npb8 ? ni8 : i8) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic << "); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << "," << (*it)->pvec[2] << "," |
| | << (*it)->pvec[3] << "," << (*it)->pvec[4] << "," << (*it)->pvec[5] |
| | << "," << (*it)->pvec[6] << "," << (*it)->pvec[7] << std::endl; |
| | break; |
| | } |
| | case TangentCircumf: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintTangentCircumf * c" << ic |
| | << "=new ConstraintTangentCircumf(" |
| | << (static_cast<ConstraintTangentCircumf*>(*it)->getInternal() |
| | ? "true" |
| | : "false") |
| | << ");" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic |
| | << "); // addresses = " << (*it)->pvec[0] << "," << (*it)->pvec[1] |
| | << "," << (*it)->pvec[2] << "," << (*it)->pvec[3] << "," |
| | << (*it)->pvec[4] << "," << (*it)->pvec[5] << std::endl; |
| | break; |
| | } |
| | case PointOnEllipse: { |
| | VEC_pD::iterator p1 = std::ranges::find(plist, (*it)->pvec[0]); |
| | VEC_pD::iterator p2 = std::ranges::find(plist, (*it)->pvec[1]); |
| | VEC_pD::iterator p3 = std::ranges::find(plist, (*it)->pvec[2]); |
| | VEC_pD::iterator p4 = std::ranges::find(plist, (*it)->pvec[3]); |
| | VEC_pD::iterator p5 = std::ranges::find(plist, (*it)->pvec[4]); |
| | VEC_pD::iterator p6 = std::ranges::find(plist, (*it)->pvec[5]); |
| | VEC_pD::iterator p7 = std::ranges::find(plist, (*it)->pvec[6]); |
| | size_t i1 = std::distance(plist.begin(), p1); |
| | size_t i2 = std::distance(plist.begin(), p2); |
| | size_t i3 = std::distance(plist.begin(), p3); |
| | size_t i4 = std::distance(plist.begin(), p4); |
| | size_t i5 = std::distance(plist.begin(), p5); |
| | size_t i6 = std::distance(plist.begin(), p6); |
| | size_t i7 = std::distance(plist.begin(), p7); |
| |
|
| | bool npb1 = false; |
| | VEC_pD::iterator np1 = std::ranges::find(clist_params_, (*it)->pvec[0]); |
| | size_t ni1 = std::distance(clist_params_.begin(), np1); |
| |
|
| | if (i1 == plist.size()) { |
| | if (ni1 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[0]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[0]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[0] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb1 = true; |
| | } |
| |
|
| | bool npb2 = false; |
| | VEC_pD::iterator np2 = std::ranges::find(clist_params_, (*it)->pvec[1]); |
| | size_t ni2 = std::distance(clist_params_.begin(), np2); |
| |
|
| | if (i2 == plist.size()) { |
| | if (ni2 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[1]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[1]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[1] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb2 = true; |
| | } |
| |
|
| | bool npb3 = false; |
| | VEC_pD::iterator np3 = std::ranges::find(clist_params_, (*it)->pvec[2]); |
| | size_t ni3 = std::distance(clist_params_.begin(), np3); |
| |
|
| | if (i3 == plist.size()) { |
| | if (ni3 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[2]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[2]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[2] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb3 = true; |
| | } |
| |
|
| | bool npb4 = false; |
| | VEC_pD::iterator np4 = std::ranges::find(clist_params_, (*it)->pvec[3]); |
| | size_t ni4 = std::distance(clist_params_.begin(), np4); |
| |
|
| | if (i4 == plist.size()) { |
| | if (ni4 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[3]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[3]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[3] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb4 = true; |
| | } |
| |
|
| | bool npb5 = false; |
| | VEC_pD::iterator np5 = std::ranges::find(clist_params_, (*it)->pvec[4]); |
| | size_t ni5 = std::distance(clist_params_.begin(), np5); |
| |
|
| | if (i5 == plist.size()) { |
| | if (ni5 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[4]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[4]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[4] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb5 = true; |
| | } |
| |
|
| | bool npb6 = false; |
| | VEC_pD::iterator np6 = std::ranges::find(clist_params_, (*it)->pvec[5]); |
| | size_t ni6 = std::distance(clist_params_.begin(), np6); |
| |
|
| | if (i6 == plist.size()) { |
| | if (ni6 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[5]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[5]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[5] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb6 = true; |
| | } |
| |
|
| | bool npb7 = false; |
| | VEC_pD::iterator np7 = std::ranges::find(clist_params_, (*it)->pvec[6]); |
| | size_t ni7 = std::distance(clist_params_.begin(), np7); |
| |
|
| | if (i7 == plist.size()) { |
| | if (ni7 == clist_params_.size()) { |
| | subsystemfile |
| | << "// Address not in System params...rebuilding into clist_params_" |
| | << std::endl; |
| | clist_params_.push_back((*it)->pvec[6]); |
| | subsystemfile << "clist_params_.push_back(new double(" << *((*it)->pvec[6]) |
| | << ")); // " << icp << " address: " << (void*)(*it)->pvec[6] |
| | << std::endl; |
| | icp++; |
| | } |
| | npb7 = true; |
| | } |
| |
|
| | subsystemfile << "ConstraintPointOnEllipse * c" << ic |
| | << "=new ConstraintPointOnEllipse();" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb1 ? ("clist_params_[") : ("plist_[")) << (npb1 ? ni1 : i1) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb2 ? ("clist_params_[") : ("plist_[")) << (npb2 ? ni2 : i2) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb3 ? ("clist_params_[") : ("plist_[")) << (npb3 ? ni3 : i3) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb4 ? ("clist_params_[") : ("plist_[")) << (npb4 ? ni4 : i4) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb5 ? ("clist_params_[") : ("plist_[")) << (npb5 ? ni5 : i5) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb6 ? ("clist_params_[") : ("plist_[")) << (npb6 ? ni6 : i6) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->pvec.push_back(" |
| | << (npb7 ? ("clist_params_[") : ("plist_[")) << (npb7 ? ni7 : i7) |
| | << "]);" << std::endl; |
| | subsystemfile << "c" << ic << "->origpvec=c" << ic << "->pvec;" << std::endl; |
| | subsystemfile << "c" << ic << "->rescale();" << std::endl; |
| | subsystemfile << "clist_.push_back(c" << ic << "); // addresses = " << (*it)->pvec[0] |
| | << "," << (*it)->pvec[1] << "," << (*it)->pvec[2] << "," |
| | << (*it)->pvec[3] << "," << (*it)->pvec[4] << "," << (*it)->pvec[5] |
| | << "," << (*it)->pvec[6] << std::endl; |
| | break; |
| | } |
| | CASE_NOT_IMP(TangentEllipseLine) |
| | CASE_NOT_IMP(InternalAlignmentPoint2Ellipse) |
| | CASE_NOT_IMP(EqualMajorAxesEllipse) |
| | CASE_NOT_IMP(EllipticalArcRangeToEndPoints) |
| | CASE_NOT_IMP(AngleViaPoint) |
| | CASE_NOT_IMP(Snell) |
| | CASE_NOT_IMP(None) |
| | } |
| | } |
| |
|
| | subsystemfile.close(); |
| | } |
| | #endif |
| |
|
| | |
| | |
| | int System::solve(SubSystem* subsysA, SubSystem* subsysB, bool , bool isRedundantsolving) |
| | { |
| | int xsizeA = subsysA->pSize(); |
| | int xsizeB = subsysB->pSize(); |
| | int csizeA = subsysA->cSize(); |
| |
|
| | VEC_pD plistAB(xsizeA + xsizeB); |
| | { |
| | VEC_pD plistA, plistB; |
| | subsysA->getParamList(plistA); |
| | subsysB->getParamList(plistB); |
| |
|
| | std::sort(plistA.begin(), plistA.end()); |
| | std::sort(plistB.begin(), plistB.end()); |
| |
|
| | VEC_pD::const_iterator it; |
| | it = std::set_union(plistA.begin(), plistA.end(), plistB.begin(), plistB.end(), plistAB.begin()); |
| | plistAB.resize(it - plistAB.begin()); |
| | } |
| | int xsize = plistAB.size(); |
| |
|
| | Eigen::MatrixXd B = Eigen::MatrixXd::Identity(xsize, xsize); |
| | Eigen::MatrixXd JA(csizeA, xsize); |
| | Eigen::MatrixXd Y, Z; |
| |
|
| | Eigen::VectorXd resA(csizeA); |
| | Eigen::VectorXd lambda(csizeA), lambda0(csizeA), lambdadir(csizeA); |
| | Eigen::VectorXd x(xsize), x0(xsize), xdir(xsize), xdir1(xsize); |
| | Eigen::VectorXd grad(xsize); |
| | Eigen::VectorXd h(xsize); |
| | Eigen::VectorXd y(xsize); |
| | Eigen::VectorXd Bh(xsize); |
| |
|
| | |
| | subsysA->redirectParams(); |
| | subsysB->redirectParams(); |
| |
|
| | subsysB->getParams(plistAB, x); |
| | subsysA->getParams(plistAB, x); |
| | subsysB->setParams(plistAB, x); |
| |
|
| | subsysB->calcGrad(plistAB, grad); |
| | subsysA->calcJacobi(plistAB, JA); |
| | subsysA->calcResidual(resA); |
| |
|
| | |
| | int maxIterNumber |
| | = (isRedundantsolving |
| | ? (sketchSizeMultiplierRedundant ? maxIterRedundant * xsize : maxIterRedundant) |
| | : (sketchSizeMultiplier ? maxIter * xsize : maxIter)); |
| |
|
| | double divergingLim = 1e6 * subsysA->error() + 1e12; |
| |
|
| | double mu = 0; |
| | lambda.setZero(); |
| | for (int iter = 1; iter < maxIterNumber; iter++) { |
| | int status = qp_eq(B, grad, JA, resA, xdir, Y, Z); |
| | if (status) { |
| | break; |
| | } |
| |
|
| | x0 = x; |
| | lambda0 = lambda; |
| | lambda = Y.transpose() * (B * xdir + grad); |
| | lambdadir = lambda - lambda0; |
| |
|
| | |
| | { |
| | double eta = 0.25; |
| | double tau = 0.5; |
| | double rho = 0.5; |
| | double alpha = 1; |
| | alpha = std::min(alpha, subsysA->maxStep(plistAB, xdir)); |
| |
|
| | |
| | mu = std::max( |
| | mu, |
| | (grad.dot(xdir) + std::max(0., 0.5 * xdir.dot(B * xdir))) |
| | / ((1. - rho) * resA.lpNorm<1>()) |
| | ); |
| |
|
| | |
| | double f0 = subsysB->error() + mu * resA.lpNorm<1>(); |
| |
|
| | |
| | double deriv = grad.dot(xdir) - mu * resA.lpNorm<1>(); |
| |
|
| | x = x0 + alpha * xdir; |
| | subsysA->setParams(plistAB, x); |
| | subsysB->setParams(plistAB, x); |
| | subsysA->calcResidual(resA); |
| | double f = subsysB->error() + mu * resA.lpNorm<1>(); |
| |
|
| | |
| | bool first = true; |
| | while (f > f0 + eta * alpha * deriv) { |
| | if (first) { |
| | xdir1 = -Y * resA; |
| | x += xdir1; |
| | subsysA->setParams(plistAB, x); |
| | subsysB->setParams(plistAB, x); |
| | subsysA->calcResidual(resA); |
| | f = subsysB->error() + mu * resA.lpNorm<1>(); |
| | if (f < f0 + eta * alpha * deriv) { |
| | break; |
| | } |
| | } |
| | alpha = tau * alpha; |
| | if (alpha < 1e-8) { |
| | alpha = 0.; |
| | } |
| | x = x0 + alpha * xdir; |
| | subsysA->setParams(plistAB, x); |
| | subsysB->setParams(plistAB, x); |
| | subsysA->calcResidual(resA); |
| | f = subsysB->error() + mu * resA.lpNorm<1>(); |
| | if (alpha < 1e-8) { |
| | break; |
| | } |
| | } |
| | lambda = lambda0 + alpha * lambdadir; |
| | } |
| | h = x - x0; |
| |
|
| | y = grad - JA.transpose() * lambda; |
| | { |
| | subsysB->calcGrad(plistAB, grad); |
| | subsysA->calcJacobi(plistAB, JA); |
| | subsysA->calcResidual(resA); |
| | } |
| | y = grad - JA.transpose() * lambda - y; |
| |
|
| | if (iter > 1) { |
| | double yTh = y.dot(h); |
| | if (yTh != 0) { |
| | Bh = B * h; |
| | |
| | B += 1. / yTh * y * y.transpose(); |
| | B -= 1. / h.dot(Bh) * (Bh * Bh.transpose()); |
| | } |
| | } |
| |
|
| | double err = subsysA->error(); |
| | if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence) && err <= smallF) { |
| | break; |
| | } |
| | if (err > divergingLim || err != err) { |
| | break; |
| | } |
| | } |
| |
|
| | int ret; |
| | if (subsysA->error() <= smallF) { |
| | ret = Success; |
| | } |
| | else if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence)) { |
| | ret = Converged; |
| | } |
| | else { |
| | ret = Failed; |
| | } |
| |
|
| | subsysA->revertParams(); |
| | subsysB->revertParams(); |
| | return ret; |
| | } |
| |
|
| | void System::applySolution() |
| | { |
| | for (int cid = 0; cid < int(subSystems.size()); cid++) { |
| | if (subSystemsAux[cid]) { |
| | subSystemsAux[cid]->applySolution(); |
| | } |
| | if (subSystems[cid]) { |
| | subSystems[cid]->applySolution(); |
| | } |
| | for (MAP_pD_pD::const_iterator it = reductionmaps[cid].begin(); |
| | it != reductionmaps[cid].end(); |
| | ++it) { |
| | *(it->first) = *(it->second); |
| | } |
| | } |
| | } |
| |
|
| | void System::undoSolution() |
| | { |
| | resetToReference(); |
| | } |
| |
|
| | void System::makeReducedJacobian( |
| | Eigen::MatrixXd& J, |
| | std::map<int, int>& jacobianconstraintmap, |
| | GCS::VEC_pD& pdiagnoselist, |
| | std::map<int, int>& tagmultiplicity |
| | ) |
| | { |
| | |
| | for (int j = 0; j < int(plist.size()); j++) { |
| | auto result1 = std::ranges::find(pdrivenlist, plist[j]); |
| |
|
| | if (result1 == std::end(pdrivenlist)) { |
| | pdiagnoselist.push_back(plist[j]); |
| | } |
| | } |
| |
|
| |
|
| | J = Eigen::MatrixXd::Zero(clist.size(), pdiagnoselist.size()); |
| |
|
| | int jacobianconstraintcount = 0; |
| | int allcount = 0; |
| | for (auto& constr : clist) { |
| | constr->revertParams(); |
| | ++allcount; |
| | if (constr->getTag() >= 0 && constr->isDriving()) { |
| | jacobianconstraintcount++; |
| | for (int j = 0; j < int(pdiagnoselist.size()); j++) { |
| | J(jacobianconstraintcount - 1, j) = constr->grad(pdiagnoselist[j]); |
| | } |
| |
|
| | |
| | if (tagmultiplicity.find(constr->getTag()) == tagmultiplicity.end()) { |
| | tagmultiplicity[constr->getTag()] = 0; |
| | } |
| | else { |
| | tagmultiplicity[constr->getTag()]++; |
| | } |
| |
|
| | jacobianconstraintmap[jacobianconstraintcount - 1] = allcount - 1; |
| | } |
| | } |
| |
|
| | if (jacobianconstraintcount == 0) { |
| | J.resize(0, 0); |
| | } |
| | } |
| |
|
| | int System::diagnose(Algorithm alg) |
| | { |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | hasDiagnosis = false; |
| | if (!hasUnknowns) { |
| | dofs = -1; |
| | return dofs; |
| | } |
| |
|
| | #ifdef _DEBUG_TO_FILE |
| | SolverReportingManager::Manager().LogToFile("GCS::System::diagnose()\n"); |
| | #endif |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | if (plist.empty() || (plist.size() - pdrivenlist.size()) == 0) { |
| | hasDiagnosis = true; |
| | emptyDiagnoseMatrix = true; |
| | dofs = 0; |
| | return dofs; |
| | } |
| |
|
| | redundant.clear(); |
| | conflictingTags.clear(); |
| | redundantTags.clear(); |
| | partiallyRedundantTags.clear(); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | Eigen::MatrixXd J; |
| |
|
| | |
| | |
| | std::map<int, int> jacobianconstraintmap; |
| |
|
| | |
| | |
| | GCS::VEC_pD pdiagnoselist; |
| |
|
| | |
| | |
| | |
| | std::map<int, int> tagmultiplicity; |
| |
|
| | makeReducedJacobian(J, jacobianconstraintmap, pdiagnoselist, tagmultiplicity); |
| |
|
| | |
| | |
| | hasDiagnosis = true; |
| | dofs = pdiagnoselist.size(); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | if (autoChooseAlgorithm) { |
| | qrAlgorithm = dofs < autoQRThreshold ? EigenDenseQR : EigenSparseQR; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| |
|
| | #ifndef EIGEN_SPARSEQR_COMPATIBLE |
| | if (qrAlgorithm == EigenSparseQR) { |
| | Base::Console().warning( |
| | "SparseQR not supported by you current version of Eigen. It " |
| | "requires Eigen 3.2.2 or higher. Falling back to Dense QR\n" |
| | ); |
| | qrAlgorithm = EigenDenseQR; |
| | } |
| | #endif |
| |
|
| | if (J.rows() == 0) { |
| | return dofs; |
| | } |
| |
|
| | |
| | emptyDiagnoseMatrix = false; |
| |
|
| | if (qrAlgorithm == EigenDenseQR) { |
| | #ifdef PROFILE_DIAGNOSE |
| | Base::TimeElapsed DenseQR_start_time; |
| | #endif |
| |
|
| | int rank = 0; |
| | Eigen::MatrixXd R; |
| | Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qrJT; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | auto fut = std::async( |
| | &System::identifyDependentParametersDenseQR, |
| | this, |
| | J, |
| | jacobianconstraintmap, |
| | pdiagnoselist, |
| | true |
| | ); |
| |
|
| | makeDenseQRDecomposition(J, jacobianconstraintmap, qrJT, rank, R); |
| |
|
| | int paramsNum = qrJT.rows(); |
| | int constrNum = qrJT.cols(); |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | fut.wait(); |
| |
|
| | dofs = paramsNum - rank; |
| |
|
| | |
| | if (constrNum > rank) { |
| | |
| | int nonredundantconstrNum; |
| | identifyConflictingRedundantConstraints( |
| | alg, |
| | qrJT, |
| | jacobianconstraintmap, |
| | tagmultiplicity, |
| | pdiagnoselist, |
| | R, |
| | constrNum, |
| | rank, |
| | nonredundantconstrNum |
| | ); |
| | if (paramsNum == rank && nonredundantconstrNum > rank) { |
| | dofs = paramsNum - nonredundantconstrNum; |
| | } |
| | } |
| |
|
| | #ifdef PROFILE_DIAGNOSE |
| | Base::TimeElapsed DenseQR_end_time; |
| |
|
| | auto SolveTime = Base::TimeElapsed::diffTimeF(DenseQR_start_time, DenseQR_end_time); |
| |
|
| | Base::Console().log("\nDenseQR - Lapsed Time: %f seconds\n", SolveTime); |
| | #endif |
| | } |
| |
|
| | #ifdef EIGEN_SPARSEQR_COMPATIBLE |
| | else if (qrAlgorithm == EigenSparseQR) { |
| | # ifdef PROFILE_DIAGNOSE |
| | Base::TimeElapsed SparseQR_start_time; |
| | # endif |
| | int rank = 0; |
| | Eigen::MatrixXd R; |
| | Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int>> SqrJT; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | auto fut = std::async( |
| | &System::identifyDependentParametersSparseQR, |
| | this, |
| | J, |
| | jacobianconstraintmap, |
| | pdiagnoselist, |
| | true |
| | ); |
| |
|
| | makeSparseQRDecomposition( |
| | J, |
| | jacobianconstraintmap, |
| | SqrJT, |
| | rank, |
| | R, |
| | true, |
| | false |
| | ); |
| |
|
| | int paramsNum = SqrJT.rows(); |
| | int constrNum = SqrJT.cols(); |
| |
|
| | fut.wait(); |
| |
|
| | dofs = paramsNum - rank; |
| |
|
| | |
| | if (constrNum > rank) { |
| | int nonredundantconstrNum; |
| |
|
| | identifyConflictingRedundantConstraints( |
| | alg, |
| | SqrJT, |
| | jacobianconstraintmap, |
| | tagmultiplicity, |
| | pdiagnoselist, |
| | R, |
| | constrNum, |
| | rank, |
| | nonredundantconstrNum |
| | ); |
| |
|
| | if (paramsNum == rank && nonredundantconstrNum > rank) { |
| | |
| | dofs = paramsNum - nonredundantconstrNum; |
| | } |
| | } |
| |
|
| | # ifdef PROFILE_DIAGNOSE |
| | Base::TimeElapsed SparseQR_end_time; |
| |
|
| | auto SolveTime = Base::TimeElapsed::diffTimeF(SparseQR_start_time, SparseQR_end_time); |
| |
|
| | Base::Console().log("\nSparseQR - Lapsed Time: %f seconds\n", SolveTime); |
| | # endif |
| | } |
| | #endif |
| |
|
| | return dofs; |
| | } |
| |
|
| | void System::makeDenseQRDecomposition( |
| | const Eigen::MatrixXd& J, |
| | const std::map<int, int>& jacobianconstraintmap, |
| | Eigen::FullPivHouseholderQR<Eigen::MatrixXd>& qrJT, |
| | int& rank, |
| | Eigen::MatrixXd& R, |
| | bool transposeJ, |
| | bool silent |
| | ) |
| | { |
| |
|
| | #ifdef _GCS_DEBUG |
| | if (!silent) { |
| | SolverReportingManager::Manager().LogMatrix("J", J); |
| | } |
| | #endif |
| |
|
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | Eigen::MatrixXd Q; |
| | Eigen::MatrixXd R2; |
| | |
| | #endif |
| |
|
| | |
| | |
| | int rowsNum = 0; |
| | int colsNum = 0; |
| |
|
| | if (J.rows() > 0) { |
| | Eigen::MatrixXd JG; |
| | if (transposeJ) { |
| | JG = J.topRows(jacobianconstraintmap.size()).transpose(); |
| | } |
| | else { |
| | JG = J.topRows(jacobianconstraintmap.size()); |
| | } |
| |
|
| | if (JG.rows() > 0 && JG.cols() > 0) { |
| |
|
| | qrJT.compute(JG); |
| |
|
| | rowsNum = qrJT.rows(); |
| | colsNum = qrJT.cols(); |
| | qrJT.setThreshold(qrpivotThreshold); |
| | rank = qrJT.rank(); |
| |
|
| | if (colsNum >= rowsNum) { |
| | R = qrJT.matrixQR().triangularView<Eigen::Upper>(); |
| | } |
| | else { |
| | R = qrJT.matrixQR().topRows(colsNum).triangularView<Eigen::Upper>(); |
| | } |
| | } |
| | else { |
| | rowsNum = JG.rows(); |
| | colsNum = JG.cols(); |
| | } |
| |
|
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | R2 = qrJT.matrixQR(); |
| | Q = qrJT.matrixQ(); |
| | #endif |
| | } |
| |
|
| | if (debugMode == IterationLevel && !silent) { |
| | SolverReportingManager::Manager().LogQRSystemInformation(*this, rowsNum, colsNum, rank); |
| | } |
| |
|
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | if (J.rows() > 0 && !silent) { |
| | SolverReportingManager::Manager().LogMatrix("R", R); |
| |
|
| | SolverReportingManager::Manager().LogMatrix("R2", R2); |
| |
|
| | SolverReportingManager::Manager().LogMatrix("Q", Q); |
| | SolverReportingManager::Manager().LogMatrix("RowTransp", qrJT.rowsTranspositions()); |
| | } |
| | #endif |
| | } |
| |
|
| | #ifdef EIGEN_SPARSEQR_COMPATIBLE |
| | void System::makeSparseQRDecomposition( |
| | const Eigen::MatrixXd& J, |
| | const std::map<int, int>& jacobianconstraintmap, |
| | Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int>>& SqrJT, |
| | int& rank, |
| | Eigen::MatrixXd& R, |
| | bool transposeJ, |
| | bool silent |
| | ) |
| | { |
| |
|
| | Eigen::SparseMatrix<double> SJ; |
| |
|
| | |
| | |
| | |
| | SJ = J.sparseView(); |
| | SJ.makeCompressed(); |
| |
|
| | # ifdef _GCS_DEBUG |
| | if (!silent) { |
| | SolverReportingManager::Manager().LogMatrix("J", J); |
| | } |
| | # endif |
| |
|
| | # ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | Eigen::MatrixXd Q; |
| | Eigen::MatrixXd R2; |
| | |
| | # endif |
| |
|
| | |
| | |
| | int rowsNum = 0; |
| | int colsNum = 0; |
| |
|
| | if (SJ.rows() > 0) { |
| | Eigen::SparseMatrix<double> SJG; |
| | if (transposeJ) { |
| | SJG = SJ.topRows(jacobianconstraintmap.size()).transpose(); |
| | } |
| | else { |
| | SJG = SJ.topRows(jacobianconstraintmap.size()); |
| | } |
| |
|
| | if (SJG.rows() > 0 && SJG.cols() > 0) { |
| | SqrJT.compute(SJG); |
| | |
| | |
| | |
| | # ifdef SPARSE_Q_MATRIX |
| | Q = SqrJT.matrixQ(); |
| | |
| | # endif |
| |
|
| | rowsNum = SqrJT.rows(); |
| | colsNum = SqrJT.cols(); |
| | SqrJT.setPivotThreshold(qrpivotThreshold); |
| | rank = SqrJT.rank(); |
| |
|
| | if (colsNum >= rowsNum) { |
| | R = SqrJT.matrixR().triangularView<Eigen::Upper>(); |
| | } |
| | else { |
| | R = SqrJT.matrixR().topRows(colsNum).triangularView<Eigen::Upper>(); |
| | } |
| |
|
| | # ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | R2 = SqrJT.matrixR(); |
| | # endif |
| | } |
| | else { |
| | rowsNum = SJG.rows(); |
| | colsNum = SJG.cols(); |
| | } |
| | } |
| |
|
| | if (debugMode == IterationLevel && !silent) { |
| | SolverReportingManager::Manager().LogQRSystemInformation(*this, rowsNum, colsNum, rank); |
| | } |
| |
|
| | # ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | if (J.rows() > 0 && !silent) { |
| |
|
| | SolverReportingManager::Manager().LogMatrix("R", R); |
| |
|
| | SolverReportingManager::Manager().LogMatrix("R2", R2); |
| |
|
| | # ifdef SPARSE_Q_MATRIX |
| | SolverReportingManager::Manager().LogMatrix("Q", Q); |
| | # endif |
| | } |
| | # endif |
| | } |
| | #endif |
| |
|
| | void System::identifyDependentParametersDenseQR( |
| | const Eigen::MatrixXd& J, |
| | const std::map<int, int>& jacobianconstraintmap, |
| | const GCS::VEC_pD& pdiagnoselist, |
| | bool silent |
| | ) |
| | { |
| | Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qrJ; |
| | Eigen::MatrixXd Rparams; |
| |
|
| | int rank; |
| |
|
| | makeDenseQRDecomposition(J, jacobianconstraintmap, qrJ, rank, Rparams, false, true); |
| |
|
| | identifyDependentParameters(qrJ, Rparams, rank, pdiagnoselist, silent); |
| | } |
| |
|
| | #ifdef EIGEN_SPARSEQR_COMPATIBLE |
| | void System::identifyDependentParametersSparseQR( |
| | const Eigen::MatrixXd& J, |
| | const std::map<int, int>& jacobianconstraintmap, |
| | const GCS::VEC_pD& pdiagnoselist, |
| | bool silent |
| | ) |
| | { |
| | Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int>> SqrJ; |
| | Eigen::MatrixXd Rparams; |
| |
|
| | int nontransprank; |
| |
|
| | makeSparseQRDecomposition( |
| | J, |
| | jacobianconstraintmap, |
| | SqrJ, |
| | nontransprank, |
| | Rparams, |
| | false, |
| | true |
| | ); |
| |
|
| | identifyDependentParameters(SqrJ, Rparams, nontransprank, pdiagnoselist, silent); |
| | } |
| | #endif |
| |
|
| | template<typename T> |
| | void System::identifyDependentParameters( |
| | T& qrJ, |
| | Eigen::MatrixXd& Rparams, |
| | int rank, |
| | const GCS::VEC_pD& pdiagnoselist, |
| | bool silent |
| | ) |
| | { |
| | (void)silent; |
| | |
| |
|
| | |
| | |
| |
|
| | eliminateNonZerosOverPivotInUpperTriangularMatrix(Rparams, rank); |
| |
|
| | #ifdef _GCS_DEBUG |
| | if (!silent) { |
| | SolverReportingManager::Manager().LogMatrix("Rparams_nonzeros_over_pilot", Rparams); |
| | } |
| | #endif |
| |
|
| | pDependentParametersGroups.resize(qrJ.cols() - rank); |
| | for (int j = rank; j < qrJ.cols(); j++) { |
| | for (int row = 0; row < rank; row++) { |
| | if (fabs(Rparams(row, j)) > 1e-10) { |
| | int origCol = qrJ.colsPermutation().indices()[row]; |
| |
|
| | pDependentParametersGroups[j - rank].push_back(pdiagnoselist[origCol]); |
| | pDependentParameters.push_back(pdiagnoselist[origCol]); |
| | } |
| | } |
| | int origCol = qrJ.colsPermutation().indices()[j]; |
| |
|
| | pDependentParametersGroups[j - rank].push_back(pdiagnoselist[origCol]); |
| | pDependentParameters.push_back(pdiagnoselist[origCol]); |
| | } |
| |
|
| | #ifdef _GCS_DEBUG |
| | if (!silent) { |
| | SolverReportingManager::Manager().LogMatrix( |
| | "PermMatrix", |
| | (Eigen::MatrixXd)qrJ.colsPermutation() |
| | ); |
| |
|
| | SolverReportingManager::Manager().LogGroupOfParameters( |
| | "ParameterGroups", |
| | pDependentParametersGroups |
| | ); |
| | } |
| |
|
| | #endif |
| | } |
| |
|
| | void System::identifyDependentGeometryParametersInTransposedJacobianDenseQRDecomposition( |
| | const Eigen::FullPivHouseholderQR<Eigen::MatrixXd>& qrJT, |
| | const GCS::VEC_pD& pdiagnoselist, |
| | int paramsNum, |
| | int rank |
| | ) |
| | { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> rowPermutations; |
| |
|
| | rowPermutations.setIdentity(paramsNum); |
| |
|
| | |
| | const MatrixIndexType rowTranspositions = qrJT.rowsTranspositions(); |
| |
|
| | for (int k = 0; k < rank; ++k) { |
| | rowPermutations.applyTranspositionOnTheRight(k, rowTranspositions.coeff(k)); |
| | } |
| |
|
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | std::stringstream stream; |
| | #endif |
| |
|
| | |
| | std::set<int> indepParamCols; |
| | std::set<int> depParamCols; |
| |
|
| | for (int j = 0; j < rank; j++) { |
| |
|
| | int origRow = rowPermutations.indices()[j]; |
| |
|
| | indepParamCols.insert(origRow); |
| |
|
| | |
| | |
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | stream << "R row " << j << " = J col " << origRow << std::endl; |
| | #endif |
| | } |
| |
|
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | std::string tmp = stream.str(); |
| |
|
| | SolverReportingManager::Manager().LogString(tmp); |
| | #endif |
| |
|
| | |
| | for (int j = 0; j < paramsNum; j++) { |
| | auto result = indepParamCols.find(j); |
| | if (result == indepParamCols.end()) { |
| | depParamCols.insert(j); |
| | } |
| | } |
| |
|
| | #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX |
| | stream.flush(); |
| |
|
| | stream << "Indep params: ["; |
| | for (auto indep : indepParamCols) { |
| | stream << indep; |
| | } |
| | stream << "]" << std::endl; |
| |
|
| | stream << "Dep params: ["; |
| | for (auto dep : depParamCols) { |
| | stream << dep; |
| | } |
| | stream << "]" << std::endl; |
| |
|
| | tmp = stream.str(); |
| | SolverReportingManager::Manager().LogString(tmp); |
| | #endif |
| |
|
| |
|
| | for (auto param : depParamCols) { |
| | pDependentParameters.push_back(pdiagnoselist[param]); |
| | } |
| | } |
| |
|
| | void System::eliminateNonZerosOverPivotInUpperTriangularMatrix(Eigen::MatrixXd& R, int rank) |
| | { |
| | for (int i = 1; i < rank; i++) { |
| | |
| | assert(R(i, i) != 0); |
| | for (int row = 0; row < i; row++) { |
| | if (R(row, i) != 0) { |
| | double coef = R(row, i) / R(i, i); |
| | R.block(row, i + 1, 1, R.cols() - i - 1) -= coef |
| | * R.block(i, i + 1, 1, R.cols() - i - 1); |
| | R(row, i) = 0; |
| | } |
| | } |
| | } |
| | } |
| |
|
| | template<typename T> |
| | void System::identifyConflictingRedundantConstraints( |
| | Algorithm alg, |
| | const T& qrJT, |
| | const std::map<int, int>& jacobianconstraintmap, |
| | const std::map<int, int>& tagmultiplicity, |
| | GCS::VEC_pD& pdiagnoselist, |
| | Eigen::MatrixXd& R, |
| | int constrNum, |
| | int rank, |
| | int& nonredundantconstrNum |
| | ) |
| | { |
| | eliminateNonZerosOverPivotInUpperTriangularMatrix(R, rank); |
| |
|
| | std::vector<std::vector<Constraint*>> conflictGroups(constrNum - rank); |
| | for (int j = rank; j < constrNum; j++) { |
| | for (int row = 0; row < rank; row++) { |
| | if (fabs(R(row, j)) > 1e-10) { |
| | int origCol = qrJT.colsPermutation().indices()[row]; |
| |
|
| | conflictGroups[j - rank].push_back(clist[jacobianconstraintmap.at(origCol)]); |
| | } |
| | } |
| | int origCol = qrJT.colsPermutation().indices()[j]; |
| |
|
| | conflictGroups[j - rank].push_back(clist[jacobianconstraintmap.at(origCol)]); |
| | } |
| |
|
| | |
| | if (debugMode == IterationLevel) { |
| | SolverReportingManager::Manager().LogGroupOfConstraints( |
| | "Analysing groups of constraints of special interest", |
| | conflictGroups |
| | ); |
| | } |
| |
|
| | |
| | |
| | |
| | std::set<Constraint*> skipped; |
| | SET_I satisfiedGroups; |
| | while (1) { |
| | |
| | |
| | |
| | |
| | |
| | std::map<Constraint*, SET_I> conflictingMap; |
| | for (std::size_t i = 0; i < conflictGroups.size(); i++) { |
| | if (satisfiedGroups.count(i) != 0) { |
| | continue; |
| | } |
| |
|
| | for (const auto& constr : conflictGroups[i]) { |
| | bool isinternalalignment |
| | = (constr->isInternalAlignment() == Constraint::Alignment::InternalAlignment); |
| | bool priorityconstraint = (constr->getTag() == 0); |
| | if (!priorityconstraint && !isinternalalignment) { |
| | |
| | conflictingMap[constr].insert(i); |
| | } |
| | } |
| | } |
| |
|
| | if (conflictingMap.empty()) { |
| | break; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | auto iterMostPopular = std::max_element( |
| | conflictingMap.begin(), |
| | conflictingMap.end(), |
| | [&tagmultiplicity](const auto& pair1, const auto& pair2) { |
| | size_t sizeOfSet1 = pair1.second.size(); |
| | size_t sizeOfSet2 = pair2.second.size(); |
| | auto tag1 = pair1.first->getTag(); |
| | auto tag2 = pair2.first->getTag(); |
| |
|
| | return ( |
| | sizeOfSet2 > sizeOfSet1 |
| | || (sizeOfSet2 == sizeOfSet1 |
| | && tagmultiplicity.at(tag2) < tagmultiplicity.at(tag1)) |
| | || (sizeOfSet2 == sizeOfSet1 |
| | && tagmultiplicity.at(tag2) == tagmultiplicity.at(tag1) && tag2 > tag1) |
| | ); |
| | } |
| | ); |
| |
|
| | Constraint* mostPopular = iterMostPopular->first; |
| | int maxPopularity = iterMostPopular->second.size(); |
| |
|
| | if (!(maxPopularity > 0)) { |
| | continue; |
| | } |
| |
|
| | |
| | |
| | |
| | auto maxPopularityTag = mostPopular->getTag(); |
| |
|
| | for (const auto& [constr, conflSet] : conflictingMap) { |
| | if (!(constr->getTag() == maxPopularityTag)) { |
| | continue; |
| | } |
| |
|
| | skipped.insert(constr); |
| | std::ranges::copy(conflSet, std::inserter(satisfiedGroups, satisfiedGroups.begin())); |
| | } |
| | } |
| |
|
| | |
| | if (debugMode == IterationLevel) { |
| | SolverReportingManager::Manager().LogSetOfConstraints("Chosen redundants", skipped); |
| | } |
| |
|
| | std::vector<Constraint*> clistTmp; |
| | clistTmp.reserve(clist.size()); |
| | std::ranges::copy_if(clist, std::back_inserter(clistTmp), [&skipped](const auto& constr) { |
| | return (constr->isDriving() && skipped.count(constr) == 0); |
| | }); |
| |
|
| | SubSystem* subSysTmp = new SubSystem(clistTmp, pdiagnoselist); |
| | int res = solve(subSysTmp, true, alg, true); |
| |
|
| | if (debugMode == Minimal || debugMode == IterationLevel) { |
| | std::string solvername; |
| | switch (alg) { |
| | case 0: |
| | solvername = "BFGS"; |
| | break; |
| | case 1: |
| | solvername = "LevenbergMarquardt"; |
| | break; |
| | case 2: |
| | solvername = "DogLeg"; |
| | break; |
| | } |
| |
|
| | Base::Console().log("Sketcher::RedundantSolving-%s-\n", solvername.c_str()); |
| | } |
| |
|
| | if (res == Success) { |
| | subSysTmp->applySolution(); |
| | std::ranges::copy_if( |
| | skipped, |
| | std::inserter(redundant, redundant.begin()), |
| | [this](const auto& constr) { |
| | double err = constr->error(); |
| | return (err * err < this->convergenceRedundant); |
| | } |
| | ); |
| | resetToReference(); |
| |
|
| | if (debugMode == Minimal || debugMode == IterationLevel) { |
| | Base::Console().log("Sketcher Redundant solving: %d redundants\n", redundant.size()); |
| | } |
| |
|
| | |
| | std::vector<std::vector<Constraint*>> conflictGroupsOrig = conflictGroups; |
| | conflictGroups.clear(); |
| | for (int i = conflictGroupsOrig.size() - 1; i >= 0; i--) { |
| | auto iterRedundantEntry = std::ranges::find_if( |
| | conflictGroupsOrig[i], |
| | [this](const auto item) { return (this->redundant.count(item) > 0); } |
| | ); |
| | bool hasRedundant = (iterRedundantEntry != conflictGroupsOrig[i].end()); |
| | if (!hasRedundant) { |
| | conflictGroups.push_back(conflictGroupsOrig[i]); |
| | continue; |
| | } |
| |
|
| | if (debugMode == IterationLevel) { |
| | Base::Console().log( |
| | "(Partially) Redundant, Group %d, index %d, Tag: %d\n", |
| | i, |
| | iterRedundantEntry - conflictGroupsOrig[i].begin(), |
| | (*iterRedundantEntry)->getTag() |
| | ); |
| | } |
| |
|
| | constrNum--; |
| | } |
| | } |
| | delete subSysTmp; |
| |
|
| | |
| | SET_I conflictingTagsSet; |
| | for (const auto& cGroup : conflictGroups) { |
| | |
| | std::ranges::transform( |
| | cGroup, |
| | std::inserter(conflictingTagsSet, conflictingTagsSet.begin()), |
| | [](const auto& constr) { |
| | bool isinternalalignment |
| | = (constr->isInternalAlignment() == Constraint::Alignment::InternalAlignment); |
| | return (isinternalalignment ? 0 : constr->getTag()); |
| | } |
| | ); |
| | } |
| |
|
| | |
| | conflictingTagsSet.erase(0); |
| |
|
| | conflictingTags.resize(conflictingTagsSet.size()); |
| | std::ranges::copy(conflictingTagsSet, conflictingTags.begin()); |
| |
|
| | |
| | SET_I redundantTagsSet, partiallyRedundantTagsSet; |
| | for (const auto& constr : redundant) { |
| | redundantTagsSet.insert(constr->getTag()); |
| | partiallyRedundantTagsSet.insert(constr->getTag()); |
| | } |
| |
|
| | |
| | for (const auto& constr : clist) { |
| | if (redundant.count(constr) == 0) { |
| | redundantTagsSet.erase(constr->getTag()); |
| | } |
| | } |
| |
|
| | redundantTags.resize(redundantTagsSet.size()); |
| | std::ranges::copy(redundantTagsSet, redundantTags.begin()); |
| |
|
| | for (auto r : redundantTagsSet) { |
| | partiallyRedundantTagsSet.erase(r); |
| | } |
| |
|
| | partiallyRedundantTags.resize(partiallyRedundantTagsSet.size()); |
| | std::ranges::copy(partiallyRedundantTagsSet, partiallyRedundantTags.begin()); |
| |
|
| | nonredundantconstrNum = constrNum; |
| | } |
| |
|
| | void System::clearSubSystems() |
| | { |
| | isInit = false; |
| | deleteAllContent(subSystems); |
| | deleteAllContent(subSystemsAux); |
| | subSystems.clear(); |
| | subSystemsAux.clear(); |
| | } |
| |
|
| | double lineSearch(SubSystem* subsys, Eigen::VectorXd& xdir) |
| | { |
| | double f1, f2, f3, alpha1, alpha2, alpha3, alphaStar; |
| |
|
| | double alphaMax = subsys->maxStep(xdir); |
| |
|
| | Eigen::VectorXd x0, x; |
| |
|
| | |
| | subsys->getParams(x0); |
| |
|
| | |
| | alpha1 = 0.; |
| | f1 = subsys->error(); |
| |
|
| | |
| | alpha2 = 1.; |
| | x = x0 + alpha2 * xdir; |
| | subsys->setParams(x); |
| | f2 = subsys->error(); |
| |
|
| | |
| | alpha3 = alpha2 * 2; |
| | x = x0 + alpha3 * xdir; |
| | subsys->setParams(x); |
| | f3 = subsys->error(); |
| |
|
| | |
| | |
| | while (f2 > f1 || f2 > f3) { |
| | if (f2 > f1) { |
| | |
| | |
| | alpha3 = alpha2; |
| | f3 = f2; |
| | alpha2 = alpha2 / 2; |
| | x = x0 + alpha2 * xdir; |
| | subsys->setParams(x); |
| | f2 = subsys->error(); |
| | } |
| | else if (f2 > f3) { |
| | if (alpha3 >= alphaMax) { |
| | break; |
| | } |
| | |
| | |
| | alpha2 = alpha3; |
| | f2 = f3; |
| | alpha3 = alpha3 * 2; |
| | x = x0 + alpha3 * xdir; |
| | subsys->setParams(x); |
| | f3 = subsys->error(); |
| | } |
| | } |
| | |
| | alphaStar = alpha2 + ((alpha2 - alpha1) * (f1 - f3)) / (3 * (f1 - 2 * f2 + f3)); |
| |
|
| | |
| | if (alphaStar >= alpha3 || alphaStar <= alpha1) { |
| | alphaStar = alpha2; |
| | } |
| |
|
| | if (alphaStar > alphaMax) { |
| | alphaStar = alphaMax; |
| | } |
| |
|
| | if (alphaStar != alphaStar) { |
| | alphaStar = 0.; |
| | } |
| |
|
| | |
| | x = x0 + alphaStar * xdir; |
| | subsys->setParams(x); |
| |
|
| | return alphaStar; |
| | } |
| |
|
| | void deleteAllContent(VEC_pD& doublevec) |
| | { |
| | for (auto& doubleptr : doublevec) { |
| | delete doubleptr; |
| | } |
| | doublevec.clear(); |
| | } |
| |
|
| | void deleteAllContent(std::vector<Constraint*>& constrvec) |
| | { |
| | for (auto& constr : constrvec) { |
| | delete constr; |
| | } |
| | constrvec.clear(); |
| | } |
| |
|
| | void deleteAllContent(std::vector<SubSystem*>& subsysvec) |
| | { |
| | for (auto& subsys : subsysvec) { |
| | delete subsys; |
| | } |
| | } |
| |
|
| | } |
| |
|