Program Listing for File NonlinearSolver.h#
↰ Return to documentation for file (include/Karana/Math/NonlinearSolver.h)
/*
*Copyright(c)2024-2025KaranaDynamicsPtyLtd.Allrightsreserved.
*
*NOTICETOUSER:
*
*Thissourcecodeand/ordocumentation(the"LicensedMaterials")is
*theconfidentialandproprietaryinformationofKaranaDynamicsInc.
*UseoftheseLicensedMaterialsisgovernedbythetermsandconditions
*ofaseparatesoftwarelicenseagreementbetweenKaranaDynamicsandthe
*Licensee("LicenseAgreement").Unlessexpresslypermittedunderthat
*agreement,anyreproduction,modification,distribution,ordisclosure
*oftheLicensedMaterials,inwholeorinpart,toanythirdparty
*withoutthepriorwrittenconsentofKaranaDynamicsisstrictlyprohibited.
*
*THELICENSEDMATERIALSAREPROVIDED"ASIS"WITHOUTWARRANTYOFANYKIND.
*KARANADYNAMICSDISCLAIMSALLWARRANTIES,EXPRESSORIMPLIED,INCLUDING
*BUTNOTLIMITEDTOWARRANTIESOFMERCHANTABILITY,NON-INFRINGEMENT,AND
*FITNESSFORAPARTICULARPURPOSE.
*
*INNOEVENTSHALLKARANADYNAMICSBELIABLEFORANYDAMAGESWHATSOEVER,
*INCLUDINGBUTNOTLIMITEDTOLOSSOFPROFITS,DATA,ORUSE,EVENIF
*ADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGES,WHETHERINCONTRACT,TORT,
*OROTHERWISEARISINGOUTOFORINCONNECTIONWITHTHELICENSEDMATERIALS.
*
*U.S.GovernmentEndUsers:TheLicensedMaterialsarea"commercialitem"
*asdefinedat48C.F.R.2.101,andareprovidedtotheU.S.Government
*onlyasacommercialenditemunderthetermsofthislicense.
*
*AnyuseoftheLicensedMaterialsinindividualorcommercialsoftwaremust
*include,intheuserdocumentationandinternalsourcecodecomments,
*thisNotice,Disclaimer,andU.S.GovernmentUseProvision.
*/
#pragmaonce
#include"Karana/KCore/LockingBase.h"
#include"Karana/Math/Defs.h"
#include<functional>
#include<memory>
#include<unsupported/Eigen/NonLinearOptimization>
#include<unsupported/Eigen/NumericalDiff>
#include<variant>
namespaceKarana::Math{
namespacekc=Karana::Core;
usingcost_fn=std::function<void(constVec&,Vec&)>;
usingjac_fn=
std::function<void(constVec&,Mat&)>;
template<typenameScalar_=double,intNX=Eigen::Dynamic,intNY=Eigen::Dynamic>
structFunctor{
usingScalar=Scalar_;
enum{
InputsAtCompileTime=NX,//NOLINT(readability-identifier-naming)
ValuesAtCompileTime=NY//NOLINT(readability-identifier-naming)
};
usingInputType=Eigen::Matrix<Scalar,InputsAtCompileTime,1>;
usingValueType=Eigen::Matrix<Scalar,ValuesAtCompileTime,1>;
usingJacobianType=Eigen::Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime>;
constint_inputs;//NOLINT(readability-identifier-naming)
constint_values;//NOLINT(readability-identifier-naming)
Functor(intinputs,intvalues)
:_inputs(inputs)
,_values(values){}
intinputs()const{return_inputs;}
intvalues()const{return_values;}
};
structDynamicFunctor:Functor<double,Eigen::Dynamic,Eigen::Dynamic>{
usingBase=Functor<double, Eigen::Dynamic, Eigen::Dynamic>;
cost_fn_f;//NOLINT(readability-identifier-naming)
jac_fn_j;//NOLINT(readability-identifier-naming)
DynamicFunctor(intdim1,intdim2,cost_fnf,jac_fnj)
:Base(dim1,dim2)
,_f(f)
,_j(j){}
intoperator()(constVec&x,Vec&fvec)const{
_f(x,fvec);
return0;
}
intdf(constVec&x,Base::JacobianType&fjac)const{
//Wemustdoacopyhere,sinceweuserow-majorandEigen'snon-linearsolversuse
//columnmajor.Ifinthefuturetheysupportrow-majororderinthenon-linear
//solvers,thenmodifythistoremovethecopy.
Matdark(fjac.rows(),fjac.cols());
_j(x,dark);
fjac=dark;
return0;
}
};
structDynamicFunctorNoJac:Functor<double,Eigen::Dynamic,Eigen::Dynamic>{
usingBase=Functor<double, Eigen::Dynamic, Eigen::Dynamic>;
cost_fn_f;//NOLINT(readability-identifier-naming)
jac_fn_j;//NOLINT(readability-identifier-naming)
DynamicFunctorNoJac(intdim1,intdim2,cost_fnf)
:Base(dim1,dim2)
,_f(f){}
intoperator()(constVec&x,Vec&fvec)const{
_f(x,fvec);
return0;
}
};
usingDynamicFunctorNumJac=Eigen::NumericalDiff<DynamicFunctorNoJac>;
usingfunctor_type=std::variant<DynamicFunctor,DynamicFunctorNumJac>;
usingsolver_type=std::variant<LevenbergMarquardt<DynamicFunctor>,
LevenbergMarquardt<DynamicFunctorNumJac>,
HybridNonLinearSolver<DynamicFunctor>,
HybridNonLinearSolver<DynamicFunctorNumJac>>;
enumSolverType{LEVENBERG_MARQUARDT,HYBRID_NON_LINEAR_SOLVER};
classNonlinearSolver:publickc::LockingBase{
public:
NonlinearSolver(
std::string_viewname,intinput_dim,intvalue_dim,cost_fnf,jac_fnj=nullptr);
statickc::ks_ptr<NonlinearSolver>
create(std::string_viewname,intinput_dim,intvalue_dim,cost_fnf,jac_fnj=nullptr);
cost_fngetF();
voidsetF(cost_fnf);
jac_fngetJac();
voidsetJac(jac_fnjac);
kc::ks_ptr<solver_type>getSolver();
voidsetSolver(constkc::ks_ptr<solver_type>&solver);
kc::ks_ptr<solver_type>createSolver(constSolverType&solver);
MatgetCachedJacobian();
doublesolve(Vec&x);
std::variant<Eigen::LevenbergMarquardtSpace::Status,
Eigen::HybridNonLinearSolverSpace::Status>
status;
protected:
void_makeCurrent()final;
private:
void_makeFunctor();
int_input_dim;
int_value_dim;
cost_fn_f;
jac_fn_j;
kc::ks_ptr<solver_type>_solver=nullptr;
std::unique_ptr<functor_type>_func;
void_createSolver(SolverTypesolver,DynamicFunctor&func);
void_createSolver(SolverTypesolver,DynamicFunctorNumJac&func);
void_solve(Eigen::LevenbergMarquardt<DynamicFunctor>&s,Vec&x);
void_solve(Eigen::LevenbergMarquardt<DynamicFunctorNumJac>&s,Vec&x);
void_solve(Eigen::HybridNonLinearSolver<DynamicFunctor>&s,Vec&x);
void_solve(Eigen::HybridNonLinearSolver<DynamicFunctorNumJac>&s,Vec&x);
};
}//namespaceKarana::Math