IGL_INLINE void igl::hessian( const Eigen::MatrixBase<DerivedV> & V, const Eigen::MatrixBase<DerivedF> & F, Eigen::SparseMatrix<Scalar>& H) { typedef typename DerivedV::Scalar denseScalar; typedef typename Eigen::Matrix<denseScalar, Eigen::Dynamic, 1> VecXd; typedef typename Eigen::SparseMatrix<Scalar> SparseMat; typedef typename Eigen::DiagonalMatrix <Scalar, Eigen::Dynamic, Eigen::Dynamic> DiagMat; int dim = V.cols(); assert((dim==2 || dim==3) && "The dimension of the vertices should be 2 or 3"); //Construct the combined gradient matric SparseMat G; igl::grad(Eigen::PlainObjectBase<DerivedV>(V), Eigen::PlainObjectBase<DerivedF>(F), G, false); SparseMat GG(F.rows(), dim*V.rows()); GG.reserve(G.nonZeros()); for(int i=0; i<dim; ++i) GG.middleCols(i*G.cols(),G.cols()) = G.middleRows(i*F.rows(),F.rows()); SparseMat D; igl::repdiag(GG,dim,D); //Compute area matrix VecXd areas; igl::doublearea(V, F, areas); DiagMat A = (0.5*areas).replicate(dim,1).asDiagonal(); //Compute FEM Hessian H = D.transpose()*A*G; }
SparseMat SparseMat::operator*(const SparseMat &right) const { if(!consolidated() || !right.consolidated()) throw ErrProgrammingError("Attempt to multiply unconsolidated SparseMats!", __FILE__, __LINE__); SparseMat result(nrows(), right.ncols()); const SparseMat rightt = right.transpose(); for(unsigned int i=0; i<nrows(); i++) { for(unsigned int j=0; j<rightt.nrows(); j++) { const_row_iterator ai = begin(i); const_row_iterator bj = rightt.begin(j); while(ai < end(i) && bj < rightt.end(j)) { if(ai.col() == bj.col()) { result.insert(i, j, (*ai)*(*bj)); ++ai; ++bj; } else if(ai.col() < bj.col()) ++ai; else ++bj; } } result.consolidate_row(i); } // result.consolidate(); result.consolidated_ = true; return result; }