void ComputeMassMat::compute(SXMatrix &M,const TetMesh&mesh, const vector<SX> &density){ assert_eq(density.size(),mesh.tets().size()); this->_density = density; _M.setZero(); computeCompactM(_M,mesh); const int n = mesh.nodes().size(); M.resize(n*3,n*3); M.setZero(); for (int i = 0; i < _M.size1(); ++i){ for (int j = 0; j < _M.size2(); ++j){ if( _M.hasNZ(i,j) ){ M.elem(i*3+0,j*3+0) = _M.elem(i,j); M.elem(i*3+1,j*3+1) = _M.elem(i,j); M.elem(i*3+2,j*3+2) = _M.elem(i,j); } } } }
void MaterialFitting::solveByNNLS(){ const SXMatrix M1 = assembleObjMatrix(); vector<SX> smooth_funs; computeSmoothObjFunctions(smooth_funs); SXMatrix obj_fun_m(M1.size1()*M1.size2()+smooth_funs.size(),1); for (int i = 0; i < M1.size1(); ++i){ for (int j = 0; j < M1.size2(); ++j) obj_fun_m.elem(i*M1.size2()+j,0) = M1.elem(i,j); } for (int i = 0; i < smooth_funs.size(); ++i){ obj_fun_m.elem(M1.size2()*M1.size2()+i,0) = smooth_funs[i]; } VSX variable_x; initAllVariables(variable_x); CasADi::SXFunction g_fun = CasADi::SXFunction(variable_x,obj_fun_m); g_fun.init(); VectorXd x0(variable_x.size()), b; x0.setZero(); CASADI::evaluate(g_fun, x0, b); b = -b; MatrixXd J = CASADI::convert<double>(g_fun.jac()); assert_eq(J.rows(), b.size()); assert_eq(J.cols(), x0.size()); VectorXd x(b.size()), w(J.cols()), zz(J.rows()); VectorXi index(J.cols()*2); getInitValue(x); int exit_code = 0; double residual = 1e-18; nnls(&J(0,0), J.rows(), J.rows(), J.cols(), &b[0], &x[0], &residual, &w[0], &zz[0], &index[0], &exit_code); INFO_LOG("residual: " << residual); print_NNLS_exit_code(exit_code); rlst.resize(x.size()); for (int i = 0; i < x.size(); ++i){ rlst[i] = x[i]; } const MatrixXd H = J.transpose()*J; SelfAdjointEigenSolver<MatrixXd> es; es.compute(H); cout << "The eigenvalues of H are: " << es.eigenvalues().transpose() << endl; }