Program Listing for File NonlinearSolver.h

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);

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