23 #include <Eigen/Dense>
29 std::pair<Eigen::VectorXd, Eigen::VectorXd>
ReadData()
33 std::cout <<
"Reading strain data..." << std::endl;
34 std::cout <<
" Units: " << std::string(f[
"/Strain"].attrs[
"Units"]) << std::endl;
35 std::cout <<
" Size: " << f[
"/Strain"].rows() << std::endl;
37 Eigen::VectorXd strain = f[
"/Strain"];
39 std::cout <<
"Reading stress data..." << std::endl;
40 std::cout <<
" Units: " << std::string(f[
"/Stress"].attrs[
"Units"]) << std::endl;
41 std::cout <<
" Size: " << f[
"/Stress"].rows() << std::endl;
43 Eigen::VectorXd stress = f[
"/Stress"];
45 return std::make_pair(strain, stress);
51 auto poly = std::make_shared<Legendre>();
52 std::vector<std::shared_ptr<IndexedScalarBasis>> bases(1, poly);
53 std::shared_ptr<MultiIndexSet> multis = MultiIndexFactory::CreateTotalOrder(1, order);
55 Eigen::MatrixXd polyCoeffs = Eigen::MatrixXd::Zero(1,multis->Size());
56 polyCoeffs(0,1) = 500.0;
58 auto polyBase = std::make_shared<BasisExpansion>(bases, multis, polyCoeffs);
59 auto expansion = std::make_shared<MonotoneExpansion>(polyBase);
69 Eigen::VectorXd
const& y,
70 std::shared_ptr<MonotoneExpansion> expansion)
72 Eigen::VectorXd coeffs = expansion->GetCoeffs();
74 Eigen::VectorXd preds(x.size());
75 Eigen::VectorXd newPreds(x.size());
76 Eigen::VectorXd newCoeffs;
78 Eigen::VectorXd resid, newResid, step, xslice;
79 Eigen::MatrixXd jac(x.size(), coeffs.size());
81 const int maxLineIts = 10;
82 const int maxIts = 20;
85 for(
int k=0;
k<x.size(); ++
k){
86 xslice = x.segment(
k,1);
87 preds(
k) = boost::any_cast<Eigen::VectorXd>(expansion->Evaluate(xslice,coeffs).at(0))(0);
91 double sse = resid.squaredNorm();
93 for(
int i=0; i<maxIts; ++i){
96 for(
int k=0;
k<x.size(); ++
k){
97 xslice = x.segment(
k,1);
98 jac.row(
k) = boost::any_cast<Eigen::MatrixXd>(expansion->Jacobian(1,0,xslice,coeffs));
102 step = jac.colPivHouseholderQr().solve(resid);
103 newCoeffs = coeffs + step;
106 for(
int k=0;
k<x.size(); ++
k){
107 xslice = x.segment(
k,1);
108 newPreds(
k) = boost::any_cast<Eigen::VectorXd>(expansion->Evaluate(xslice,newCoeffs).at(0))(0);
111 newResid = y-newPreds;
112 double newsse = newResid.squaredNorm();
116 while((newsse > sse - 1
e-7)&&(lineIt<maxLineIts)){
118 newCoeffs = coeffs + step;
121 for(
int k=0;
k<x.size(); ++
k){
122 xslice = x.segment(
k,1);
123 newPreds(
k) = boost::any_cast<Eigen::VectorXd>(expansion->Evaluate(xslice,newCoeffs).at(0))(0);
126 newResid = y-newPreds;
127 newsse = newResid.squaredNorm();
130 if(lineIt == maxLineIts){
131 std::cout <<
"WARNING: Line search failed, terminating Gauss-Newton optimizer." << std::endl;
141 std::cout <<
"Iteration " << i <<
", SSE = "<< sse << std::endl;
146 std::shared_ptr<MonotoneExpansion> expansion)
148 Eigen::VectorXd preds(x.size());
149 Eigen::VectorXd xslice;
151 for(
int k=0;
k<x.size(); ++
k){
152 xslice = x.segment(
k,1);
153 preds(
k) = boost::any_cast<Eigen::VectorXd>(expansion->Evaluate(xslice).at(0))(0);
158 f[
"/Stress"] = preds;
165 Eigen::VectorXd strain, stress;
166 std::tie(strain, stress) =
ReadData();
168 unsigned polyOrder = 7;
171 FitData(strain, stress, expansion);
void FitData(Eigen::VectorXd const &x, Eigen::VectorXd const &y, std::shared_ptr< MonotoneExpansion > expansion)
std::pair< Eigen::VectorXd, Eigen::VectorXd > ReadData()
std::shared_ptr< MonotoneExpansion > SetupExpansion(unsigned order)
void WriteResults(Eigen::VectorXd const &x, std::shared_ptr< MonotoneExpansion > expansion)
H5Object OpenFile(std::string const &filename)
Open an HDF5 file and return the root object.