Eigen::SparseMatrix<double> Condi2Joint(Eigen::SparseMatrix<double> Condi, Eigen::SparseVector<double> Pa) { // second dimension of Condi is the parent Eigen::SparseMatrix<double> Joint; Joint.resize(Condi.rows(), Condi.cols()); for (int cols = 0; cols < Condi.cols(); cols++) { Eigen::SparseVector<double> tmp_vec = Condi.block(0, cols, Condi.rows(), 1)*Pa.coeff(cols); for (int id_rows = 0; id_rows < tmp_vec.size(); id_rows++) { Joint.coeffRef(id_rows, cols) = tmp_vec.coeff(id_rows); } } Joint.prune(TOLERANCE); return Joint; }
matrix<Type> invertSparseMatrix(Eigen::SparseMatrix<Type> A){ matrix<Type> I(A.rows(),A.cols()); I.setIdentity(); Eigen::SimplicialLDLT< Eigen::SparseMatrix<Type> > ldlt(A); matrix<Type> ans = ldlt.solve(I); return ans; }
IGL_INLINE void igl::slice_into( const Eigen::SparseMatrix<T>& X, const Eigen::Matrix<int,Eigen::Dynamic,1> & R, const Eigen::Matrix<int,Eigen::Dynamic,1> & C, Eigen::SparseMatrix<T>& Y) { int xm = X.rows(); int xn = X.cols(); assert(R.size() == xm); assert(C.size() == xn); #ifndef NDEBUG int ym = Y.size(); int yn = Y.size(); assert(R.minCoeff() >= 0); assert(R.maxCoeff() < ym); assert(C.minCoeff() >= 0); assert(C.maxCoeff() < yn); #endif // create temporary dynamic sparse matrix Eigen::DynamicSparseMatrix<T, Eigen::RowMajor> dyn_Y(Y); // Iterate over outside for(int k=0; k<X.outerSize(); ++k) { // Iterate over inside for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it) { dyn_Y.coeffRef(R(it.row()),C(it.col())) = it.value(); } } Y = Eigen::SparseMatrix<T>(dyn_Y); }
ColCompressedMatrix convert_from_Eigen(const Eigen::SparseMatrix<double> &m) { assert(m.rows() == m.cols()); assert(m.isCompressed()); return ColCompressedMatrix(m.rows, m.nonZeros(), m.valuePtr(), m.outerIndexPtr(), m.innerIndexPtr()); }
void place::erodeSparse(const Eigen::SparseMatrix<double> &src, Eigen::SparseMatrix<double> &dst) { dst = Eigen::SparseMatrix<double>(src.rows(), src.cols()); std::vector<Eigen::Triplet<double>> tripletList; Eigen::MatrixXd srcNS = Eigen::MatrixXd(src); for (int i = 0; i < srcNS.cols(); ++i) { for (int j = 0; j < srcNS.rows(); ++j) { double value = 0.0; for (int k = -1; k < 1; ++k) { for (int l = -1; l < 1; ++l) { if (i + k < 0 || i + k >= srcNS.cols() || j + l < 0 || j + l >= srcNS.rows()) continue; else value = std::max(value, srcNS(j + l, i + k)); } } if (value != 0) tripletList.push_back(Eigen::Triplet<double>(j, i, value)); } } dst.setFromTriplets(tripletList.begin(), tripletList.end()); }
IGL_INLINE void igl::matlab::prepare_lhs_double( const Eigen::SparseMatrix<Vtype> & M, mxArray *plhs[]) { using namespace std; const int m = M.rows(); const int n = M.cols(); // THIS WILL NOT WORK FOR ROW-MAJOR assert(n==M.outerSize()); const int nzmax = M.nonZeros(); plhs[0] = mxCreateSparse(m, n, nzmax, mxREAL); mxArray * mx_data = plhs[0]; // Copy data immediately double * pr = mxGetPr(mx_data); mwIndex * ir = mxGetIr(mx_data); mwIndex * jc = mxGetJc(mx_data); // Iterate over outside int k = 0; for(int j=0; j<M.outerSize(); j++) { jc[j] = k; // Iterate over inside for(typename Eigen::SparseMatrix<Vtype>::InnerIterator it (M,j); it; ++it) { // copy (cast to double) pr[k] = it.value(); ir[k] = it.row(); k++; } } jc[M.outerSize()] = k; }
IGL_INLINE void igl::min( const Eigen::SparseMatrix<AType> & A, const int dim, Eigen::PlainObjectBase<DerivedB> & B, Eigen::PlainObjectBase<DerivedI> & I) { const int n = A.cols(); const int m = A.rows(); B.resize(dim==1?n:m); B.setConstant(std::numeric_limits<typename DerivedB::Scalar>::max()); I.resize(dim==1?n:m); for_each(A,[&B,&I,&dim](int i, int j,const typename DerivedB::Scalar v) { if(dim == 2) { std::swap(i,j); } // Coded as if dim == 1, assuming swap for dim == 2 if(v < B(j)) { B(j) = v; I(j) = i; } }); Eigen::VectorXi Z; find_zero(A,dim,Z); for(int j = 0;j<I.size();j++) { if(Z(j) != (dim==1?m:n) && 0 < B(j)) { B(j) = 0; I(j) = Z(j); } } }
/// return the extremal eigenvalues of Ax=cBx std::pair<double, double> generalized_extreme_eigenvalues(const Eigen::SparseMatrix<double> &Ain, const Eigen::SparseMatrix<double> &Bin) { assert(Ain.rows() == Ain.cols()); assert(Ain.rows() == Ain.cols()); assert(Ain.rows() == Bin.rows()); assert(Ain.isCompressed()); assert(Bin.isCompressed()); const int N = static_cast<int>(Ain.rows()); /* mkl_sparse_d_gv input parameters */ char which = 'S'; /* Which eigenvalues to calculate. ('L' - largest (algebraic) eigenvalues, 'S' - smallest (algebraic) eigenvalues) */ int pm[128]; /* This array is used to pass various parameters to Extended Eigensolver Extensions routines. */ int k0 = 1; /* Desired number of max/min eigenvalues */ /* mkl_sparse_d_gv output parameters */ int k; /* Number of eigenvalues found (might be less than k0). */ double E_small[3]; /* Eigenvalues */ double E_large[3]; /* Eigenvalues */ double X[3]; /* Eigenvectors */ double res[3]; /* Residual */ /* Local variables */ int compute_vectors = 0; /* Flag to compute eigenvectors */ int tol = 7; /* Tolerance */ /* Sparse BLAS IE variables */ sparse_status_t status; ConvertToMklResult A = to_mkl(Ain, status); // TODO: check A.status; ConvertToMklResult B = to_mkl(Bin, status); // TODO: check B.status; /* Step 2. Call mkl_sparse_ee_init to define default input values */ mkl_sparse_ee_init(pm); pm[1] = tol; /* Set tolerance */ pm[6] = compute_vectors; /* Step 3. Solve the standard Ax = ex eigenvalue problem. */ which = 'S'; const int infoS = mkl_sparse_d_gv(&which, pm, A.matrix, A.descr, B.matrix, B.descr, k0, &k, E_small, X, res); assert(infoS == 0); which = 'L'; const int infoL = mkl_sparse_d_gv(&which, pm, A.matrix, A.descr, B.matrix, B.descr, k0, &k, E_large, X, res); assert(infoL == 0); mkl_sparse_destroy(A.matrix); mkl_sparse_destroy(B.matrix); return {E_small[0], E_large[0]}; // todo: return the right thing }
Mat::Mat(vector<string> _row_names, vector<string> _col_names, Eigen::SparseMatrix<double> _matrix,MatType _mattype) { row_names = _row_names; col_names = _col_names; assert(row_names.size() == _matrix.rows()); assert(col_names.size() == _matrix.cols()); matrix = _matrix; mattype = _mattype; }
IGL_INLINE void igl::components( const Eigen::SparseMatrix<AScalar> & A, Eigen::PlainObjectBase<DerivedC> & C, Eigen::PlainObjectBase<Derivedcounts> & counts) { using namespace Eigen; using namespace std; assert(A.rows() == A.cols() && "A should be square."); const size_t n = A.rows(); Array<bool,Dynamic,1> seen = Array<bool,Dynamic,1>::Zero(n,1); C.resize(n,1); typename DerivedC::Scalar id = 0; vector<typename Derivedcounts::Scalar> vcounts; // breadth first search for(int k=0; k<A.outerSize(); ++k) { if(seen(k)) { continue; } queue<int> Q; Q.push(k); vcounts.push_back(0); while(!Q.empty()) { const int f = Q.front(); Q.pop(); if(seen(f)) { continue; } seen(f) = true; C(f,0) = id; vcounts[id]++; // Iterate over inside for(typename SparseMatrix<AScalar>::InnerIterator it (A,f); it; ++it) { const int g = it.index(); if(!seen(g) && it.value()) { Q.push(g); } } } id++; } assert((size_t) id == vcounts.size()); const size_t ncc = vcounts.size(); assert((size_t)C.maxCoeff()+1 == ncc); counts.resize(ncc,1); for(size_t i = 0;i<ncc;i++) { counts(i) = vcounts[i]; } }
inline void space_operator( Eigen::SparseMatrix<double>& result, Eigen::SparseMatrix<double>& laplace, const double multiplier, Eigen::SparseMatrix<double>& unit_matrix) { result.resize(unit_matrix.rows(), unit_matrix.cols()); result = laplace*multiplier+unit_matrix; }
Eigen::SparseMatrix<double> joint2conditional(Eigen::SparseMatrix<double> edgePot)// pa is the second dimension { // second dimension of edgePot is the parent Eigen::SparseMatrix<double> Conditional; Conditional.resize(edgePot.rows(), edgePot.cols()); Eigen::SparseVector<double> Parent_Marginal; Parent_Marginal.resize(edgePot.cols()); for (int id_col = 0; id_col < edgePot.cols(); id_col++) { Eigen::SparseVector<double> tmp_vec = edgePot.block(0, id_col, edgePot.rows(), 1); Parent_Marginal.coeffRef(id_col) = tmp_vec.sum(); if (Parent_Marginal.coeff(id_col)>TOLERANCE) for (int id_row = 0; id_row < edgePot.rows(); id_row++) { Conditional.coeffRef(id_row, id_col) = edgePot.coeff(id_row, id_col) / Parent_Marginal.coeff(id_col); } } Conditional.makeCompressed(); Conditional.prune(TOLERANCE); return Conditional; }
TEST(slice_into, sparse_identity) { Eigen::SparseMatrix<double> A = Eigen::MatrixXd::Random(10,9).sparseView(); Eigen::VectorXi I = Eigen::VectorXi::LinSpaced(A.rows(),0,A.rows()-1); Eigen::VectorXi J = Eigen::VectorXi::LinSpaced(A.cols(),0,A.cols()-1); { Eigen::SparseMatrix<double> B(I.maxCoeff()+1,J.maxCoeff()+1); igl::slice_into(A,I,J,B); test_common::assert_eq(A,B); } { Eigen::SparseMatrix<double> B(I.maxCoeff()+1,A.cols()); igl::slice_into(A,I,1,B); test_common::assert_eq(A,B); } { Eigen::SparseMatrix<double> B(A.rows(),J.maxCoeff()+1); igl::slice_into(A,J,2,B); test_common::assert_eq(A,B); } }
TEST(slice, sparse_identity) { Eigen::SparseMatrix<double> A = Eigen::MatrixXd::Random(10,9).sparseView(); Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi >(A.rows(),0,A.rows()-1); Eigen::VectorXi J = igl::LinSpaced<Eigen::VectorXi >(A.cols(),0,A.cols()-1); { Eigen::SparseMatrix<double> B; igl::slice(A,I,J,B); test_common::assert_eq(A,B); } { Eigen::SparseMatrix<double> B; igl::slice(A,I,1,B); test_common::assert_eq(A,B); } { Eigen::SparseMatrix<double> B; igl::slice(A,J,2,B); test_common::assert_eq(A,B); } }
IGL_INLINE void igl::cat( const int dim, const Eigen::SparseMatrix<Scalar> & A, const Eigen::SparseMatrix<Scalar> & B, Eigen::SparseMatrix<Scalar> & C) { assert(dim == 1 || dim == 2); using namespace Eigen; // Special case if B or A is empty if(A.size() == 0) { C = B; return; } if(B.size() == 0) { C = A; return; } DynamicSparseMatrix<Scalar, RowMajor> dyn_C; if(dim == 1) { assert(A.cols() == B.cols()); dyn_C.resize(A.rows()+B.rows(),A.cols()); }else if(dim == 2) { assert(A.rows() == B.rows()); dyn_C.resize(A.rows(),A.cols()+B.cols()); }else { fprintf(stderr,"cat.h: Error: Unsupported dimension %d\n",dim); } dyn_C.reserve(A.nonZeros()+B.nonZeros()); // Iterate over outside of A for(int k=0; k<A.outerSize(); ++k) { // Iterate over inside for(typename SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it) { dyn_C.coeffRef(it.row(),it.col()) += it.value(); } } // Iterate over outside of B for(int k=0; k<B.outerSize(); ++k) { // Iterate over inside for(typename SparseMatrix<Scalar>::InnerIterator it (B,k); it; ++it) { int r = (dim == 1 ? A.rows()+it.row() : it.row()); int c = (dim == 2 ? A.cols()+it.col() : it.col()); dyn_C.coeffRef(r,c) += it.value(); } } C = SparseMatrix<Scalar>(dyn_C); }
IGL_INLINE void igl::repdiag( const Eigen::SparseMatrix<T>& A, const int d, Eigen::SparseMatrix<T>& B) { using namespace std; using namespace Eigen; int m = A.rows(); int n = A.cols(); vector<Triplet<T> > IJV; IJV.reserve(A.nonZeros()*d); // Loop outer level for (int k=0; k<A.outerSize(); ++k) { // loop inner level for (typename Eigen::SparseMatrix<T>::InnerIterator it(A,k); it; ++it) { for(int i = 0;i<d;i++) { IJV.push_back(Triplet<T>(i*m+it.row(),i*n+it.col(),it.value())); } } } B.resize(m*d,n*d); B.setFromTriplets(IJV.begin(),IJV.end()); // Q: Why is this **Very** slow? //int m = A.rows(); //int n = A.cols(); //B.resize(m*d,n*d); //// Reserve enough space for new non zeros //B.reserve(d*A.nonZeros()); //// loop over reps //for(int i=0;i<d;i++) //{ // // Loop outer level // for (int k=0; k<A.outerSize(); ++k) // { // // loop inner level // for (typename Eigen::SparseMatrix<T>::InnerIterator it(A,k); it; ++it) // { // B.insert(i*m+it.row(),i*n+it.col()) = it.value(); // } // } //} //B.makeCompressed(); }
IGL_INLINE void igl::harwell_boeing( const Eigen::SparseMatrix<Scalar> & A, int & num_rows, std::vector<Scalar> & V, std::vector<Index> & R, std::vector<Index> & C) { num_rows = A.rows(); int num_cols = A.cols(); int nnz = A.nonZeros(); V.resize(nnz); R.resize(nnz); C.resize(num_cols+1); // Assumes outersize is columns assert(A.cols() == A.outerSize()); int column_pointer = 0; int i = 0; int k = 0; // Iterate over outside for(; k<A.outerSize(); ++k) { C[k] = column_pointer; // Iterate over inside for(typename Eigen::SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it) { V[i] = it.value(); R[i] = it.row(); i++; // Also increment column pointer column_pointer++; } } // by convention C[num_cols] = nnz C[k] = column_pointer; }
Eigen::SparseMatrix<Type> kronecker(Eigen::SparseMatrix<Type> x, Eigen::SparseMatrix<Type> y){ typedef Eigen::Triplet<Type> T; typedef typename Eigen::SparseMatrix<Type>::InnerIterator Iterator; std::vector<T> tripletList; int n1=x.rows(),n2=x.cols(),n3=y.rows(),n4=y.cols(); int i,j,k,l; // Loop over nonzeros of x for (int cx=0; cx<x.outerSize(); cx++) for (Iterator itx(x,cx); itx; ++itx) // Loop over nonzeros of y for (int cy=0; cy<y.outerSize(); cy++) for (Iterator ity(y,cy); ity; ++ity) { i=itx.row(); j=itx.col(); k=ity.row(); l=ity.col(); tripletList.push_back(T(i*n3+k,j*n4+l, itx.value()*ity.value() )); } Eigen::SparseMatrix<Type> mat(n1*n3,n2*n4); mat.setFromTriplets(tripletList.begin(), tripletList.end()); return mat; }
inline void fastSparseDiagProduct(const Eigen::SparseMatrix<double>& lhs, const std::vector<double>& rhs, Eigen::SparseMatrix<double>& res) { res = lhs; // Multiply columns by diagonal rhs. int n = res.cols(); for (int col = 0; col < n; ++col) { typedef Eigen::SparseMatrix<double>::InnerIterator It; for (It it(res, col); it; ++it) { it.valueRef() *= rhs[col]; } } }
IGL_INLINE void igl::full( const Eigen::SparseMatrix<T> & A, Eigen::PlainObjectBase<DerivedB>& B) { assert(false && "Obsolete. Just call B = Matrix(A)"); using namespace Eigen; B = PlainObjectBase<DerivedB >::Zero(A.rows(),A.cols()); // Iterate over outside for(int k=0; k<A.outerSize(); ++k) { // Iterate over inside for(typename SparseMatrix<T>::InnerIterator it (A,k); it; ++it) { B(it.row(),it.col()) = it.value(); } } }
inline std::unique_ptr<giss::VectorSparseMatrix> Eigen_to_giss( Eigen::SparseMatrix<double> const &mat) { std::unique_ptr<giss::VectorSparseMatrix> ret( new giss::VectorSparseMatrix(giss::SparseDescr( mat.rows(), mat.cols()))); int nz = mat.nonZeros(); ret->reserve(nz); for (int k=0; k<mat.outerSize(); ++k) { for (Eigen::SparseMatrix<double>::InnerIterator it(mat,k); it; ++it) { ret->set(it.row(), it.col(), it.value(), SparseMatrix::DuplicatePolicy::ADD); } } return ret; }
void NewtonIterationBlackoilInterleaved::formInterleavedSystem(const std::vector<ADB>& eqs, const Eigen::SparseMatrix<double, Eigen::RowMajor>& A, Mat& istlA) const { const int np = eqs.size(); // Find sparsity structure as union of basic block sparsity structures, // corresponding to the jacobians with respect to pressure. // Use addition to get to the union structure. Eigen::SparseMatrix<double> structure = eqs[0].derivative()[0]; for (int phase = 0; phase < np; ++phase) { structure += eqs[phase].derivative()[0]; } Eigen::SparseMatrix<double, Eigen::RowMajor> s = structure; // Create ISTL matrix with interleaved rows and columns (block structured). assert(np == 3); istlA.setSize(s.rows(), s.cols(), s.nonZeros()); istlA.setBuildMode(Mat::row_wise); const int* ia = s.outerIndexPtr(); const int* ja = s.innerIndexPtr(); for (Mat::CreateIterator row = istlA.createbegin(); row != istlA.createend(); ++row) { int ri = row.index(); for (int i = ia[ri]; i < ia[ri + 1]; ++i) { row.insert(ja[i]); } } const int size = s.rows(); Span span[3] = { Span(size, 1, 0), Span(size, 1, size), Span(size, 1, 2*size) }; for (int row = 0; row < size; ++row) { for (int col_ix = ia[row]; col_ix < ia[row + 1]; ++col_ix) { const int col = ja[col_ix]; MatrixBlockType block; for (int p1 = 0; p1 < np; ++p1) { for (int p2 = 0; p2 < np; ++p2) { block[p1][p2] = A.coeff(span[p1][row], span[p2][col]); } } istlA[row][col] = block; } } }
Eigen::SparseMatrix<double> normProbMatrix(Eigen::SparseMatrix<double> P) { // each column is a probability simplex Eigen::SparseMatrix<double> P_norm; P_norm.resize(P.rows(), P.cols()); for (int col = 0; col < P.cols(); col++) { //SparseVector<double> A_col_sparse = A_sparse.block(0, i, A_sparse.rows(),1); SparseVector<double> P_vec = P.block(0, col, P.rows(), 1); SparseVector<double> P_vec_norm; P_vec_norm.resize(P_vec.size()); P_vec_norm = normProbVector(P_vec); for (int id_row = 0; id_row < P.rows(); id_row++) { P_norm.coeffRef(id_row, col) = P_vec_norm.coeff(id_row); } } P_norm.makeCompressed(); P_norm.prune(TOLERANCE); return P_norm; }
//update random Vectors void updateMatrix(Eigen::SparseMatrix<double,Eigen::RowMajor>& randomMatrix, const Eigen::SparseMatrix<int,Eigen::RowMajor>& adjacencyMatrix, int itr) { int numberOfRVector = randomMatrix.rows(); int numberOfVertice = randomMatrix.cols(); std::vector<double> rowSum = getRowSum(adjacencyMatrix); for(int i=0; i<numberOfRVector;++i){ for(int h=0;h<itr;++h){ Eigen::SparseMatrix<double,Eigen::RowMajor> middleValueMatrix(numberOfVertice,1); middleValueMatrix.reserve(1); for(int j = 0; j<numberOfVertice; ++j){ Eigen::SparseMatrix<double,Eigen::RowMajor> v1(1,numberOfVertice), v2(numberOfVertice,1); v1.reserve(numberOfVertice); v2.reserve(1); v1 = adjacencyMatrix.cast<double>().innerVector(j); v2 = randomMatrix.innerVector(h).transpose(); Eigen::SparseMatrix<double,Eigen::RowMajor> middleValue1 = v1*v2; double middleValue = 0; if(rowSum[j] != 0){ middleValue = (*middleValue1.valuePtr())/rowSum[j]; } else { middleValue = 1; } middleValueMatrix.insert(j,0) = middleValue; } Eigen::SparseMatrix<double,Eigen::RowMajor> right = middleValueMatrix.transpose(); Eigen::SparseMatrix<double,Eigen::RowMajor> left = randomMatrix.innerVector(i); randomMatrix.innerVector(i) = 0.5*(left + right); } } }
double L2R_Huber_SVC::predict(const std::string fileNameLibSVMFormat, Eigen::VectorXd &w) { Eigen::SparseMatrix<double, 1> vX; Eigen::ArrayXd vy; const char *fn = fileNameLibSVMFormat.c_str(); read_LibSVMdata1(fn, vX, vy); // loadLib(fileNameLibSVMFormat, vX, vy); int vl = vX.rows(); int vn = vX.cols(); int success = 0; if (vn != w.size()) { w.conservativeResize(vn); } Eigen::ArrayXd prob = vy * (vX * w).array(); for (int i = 0; i < vl; ++i) { if (prob.coeffRef(i) >= 0.0) ++success; } return (double)success / vl; }
IGL_INLINE void igl::components( const Eigen::SparseMatrix<AScalar> & A, Eigen::PlainObjectBase<DerivedC> & C) { assert(A.rows() == A.cols()); using namespace Eigen; // THIS IS DENSE: //boost::adjacency_matrix<boost::undirectedS> bA(A.rows()); boost::adjacency_list<boost::vecS,boost::vecS,boost::undirectedS> bA(A.rows()); for(int j=0; j<A.outerSize();j++) { // Iterate over inside for(typename SparseMatrix<AScalar>::InnerIterator it (A,j); it; ++it) { if(0 != it.value()) { boost::add_edge(it.row(),it.col(),bA); } } } C.resize(A.rows(),1); boost::connected_components(bA,C.data()); }
IGL_INLINE void igl::sum( const Eigen::SparseMatrix<T>& X, const int dim, Eigen::SparseVector<T>& S) { // dim must be 2 or 1 assert(dim == 1 || dim == 2); // Get size of input int m = X.rows(); int n = X.cols(); // resize output if(dim==1) { S = Eigen::SparseVector<T>(n); }else { S = Eigen::SparseVector<T>(m); } // Iterate over outside for(int k=0; k<X.outerSize(); ++k) { // Iterate over inside for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it) { if(dim == 1) { S.coeffRef(it.col()) += it.value(); }else { S.coeffRef(it.row()) += it.value(); } } } }
IGL_INLINE void igl::slice( const Eigen::SparseMatrix<TX>& X, const Eigen::Matrix<int,Eigen::Dynamic,1> & R, const Eigen::Matrix<int,Eigen::Dynamic,1> & C, Eigen::SparseMatrix<TY>& Y) { #if 1 int xm = X.rows(); int xn = X.cols(); int ym = R.size(); int yn = C.size(); // special case when R or C is empty if(ym == 0 || yn == 0) { Y.resize(ym,yn); return; } assert(R.minCoeff() >= 0); assert(R.maxCoeff() < xm); assert(C.minCoeff() >= 0); assert(C.maxCoeff() < xn); // Build reindexing maps for columns and rows, -1 means not in map std::vector<std::vector<int> > RI; RI.resize(xm); for(int i = 0;i<ym;i++) { RI[R(i)].push_back(i); } std::vector<std::vector<int> > CI; CI.resize(xn); // initialize to -1 for(int i = 0;i<yn;i++) { CI[C(i)].push_back(i); } // Resize output Eigen::DynamicSparseMatrix<TY, Eigen::RowMajor> dyn_Y(ym,yn); // Take a guess at the number of nonzeros (this assumes uniform distribution // not banded or heavily diagonal) dyn_Y.reserve((X.nonZeros()/(X.rows()*X.cols())) * (ym*yn)); // Iterate over outside for(int k=0; k<X.outerSize(); ++k) { // Iterate over inside for(typename Eigen::SparseMatrix<TX>::InnerIterator it (X,k); it; ++it) { std::vector<int>::iterator rit, cit; for(rit = RI[it.row()].begin();rit != RI[it.row()].end(); rit++) { for(cit = CI[it.col()].begin();cit != CI[it.col()].end(); cit++) { dyn_Y.coeffRef(*rit,*cit) = it.value(); } } } } Y = Eigen::SparseMatrix<TY>(dyn_Y); #else // Alec: This is _not_ valid for arbitrary R,C since they don't necessary // representation a strict permutation of the rows and columns: rows or // columns could be removed or replicated. The removal of rows seems to be // handled here (although it's not clear if there is a performance gain when // the #removals >> #remains). If this is sufficiently faster than the // correct code above, one could test whether all entries in R and C are // unique and apply the permutation version if appropriate. // int xm = X.rows(); int xn = X.cols(); int ym = R.size(); int yn = C.size(); // special case when R or C is empty if(ym == 0 || yn == 0) { Y.resize(ym,yn); return; } assert(R.minCoeff() >= 0); assert(R.maxCoeff() < xm); assert(C.minCoeff() >= 0); assert(C.maxCoeff() < xn); // initialize row and col permutation vectors Eigen::VectorXi rowIndexVec = Eigen::VectorXi::LinSpaced(xm,0,xm-1); Eigen::VectorXi rowPermVec = Eigen::VectorXi::LinSpaced(xm,0,xm-1); for(int i=0;i<ym;i++) { int pos = rowIndexVec.coeffRef(R(i)); if(pos != i) { int& val = rowPermVec.coeffRef(i); std::swap(rowIndexVec.coeffRef(val),rowIndexVec.coeffRef(R(i))); std::swap(rowPermVec.coeffRef(i),rowPermVec.coeffRef(pos)); } } Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,int> rowPerm(rowIndexVec); Eigen::VectorXi colIndexVec = Eigen::VectorXi::LinSpaced(xn,0,xn-1); Eigen::VectorXi colPermVec = Eigen::VectorXi::LinSpaced(xn,0,xn-1); for(int i=0;i<yn;i++) { int pos = colIndexVec.coeffRef(C(i)); if(pos != i) { int& val = colPermVec.coeffRef(i); std::swap(colIndexVec.coeffRef(val),colIndexVec.coeffRef(C(i))); std::swap(colPermVec.coeffRef(i),colPermVec.coeffRef(pos)); } } Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,int> colPerm(colPermVec); Eigen::SparseMatrix<T> M = (rowPerm * X); Y = (M * colPerm).block(0,0,ym,yn); #endif }
void Poisson_LIMSolver2D::prepareProblemData(std::vector<int>& hessRowIdx, std::vector<int>& hessColIdx) { const int numNodes = mesh->InitalVertices->rows(); // create sparse gradient operator matrix Eigen::SparseMatrix<double> tempG; Eigen::VectorXd dAreas,dAreasTemp; Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> vertices(*mesh->DeformedVertices); Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic> faces(*mesh->Triangles); igl::grad(vertices,faces,tempG); // Only get x and y derivatives of elements as z is zero int newRowSize = 2.0/3.0*tempG.rows(); std::vector<Eigen::Triplet<double> > triplets; for (int k=0;k<tempG.outerSize();++k) { for (Eigen::SparseMatrix<double>::InnerIterator it(tempG,k);it;++it) { int row = it.row(); int col = it.col(); if(row < newRowSize) { triplets.push_back(Eigen::Triplet<double>(row,col,it.value())); } } } tempG.setZero(); tempG.resize(newRowSize,tempG.cols()); tempG.setFromTriplets(triplets.begin(), triplets.end()); // Extend gradient operator matrix for x and y scalar function triplets.clear(); G.resize(newRowSize*2,tempG.cols()*2); for (int k=0;k<tempG.outerSize();++k) { for (Eigen::SparseMatrix<double>::InnerIterator it(tempG,k);it;++it) { int row = it.row()*2; int col = it.col()*2; triplets.push_back(Eigen::Triplet<double>(row,col,it.value())); triplets.push_back(Eigen::Triplet<double>(row+1,col+1,it.value())); } } G.setFromTriplets(triplets.begin(), triplets.end()); // Compute area weights Eigen::SparseMatrix<double> M; igl::doublearea(vertices,faces,dAreas); triplets.clear(); M.resize(dAreas.rows()*4,dAreas.rows()*4); for(int r=0;r<dAreas.rows();r++) { int id = 4*r; triplets.push_back(Eigen::Triplet<double>(id,id,dAreas(r))); triplets.push_back(Eigen::Triplet<double>(id+1,id+1,dAreas(r))); triplets.push_back(Eigen::Triplet<double>(id+2,id+2,dAreas(r))); triplets.push_back(Eigen::Triplet<double>(id+3,id+3,dAreas(r))); } M.setFromTriplets(triplets.begin(),triplets.end()); // Compute laplacian L = 0.5*G.transpose()*M*G; for (int k=0;k<L.outerSize();++k) { for (Eigen::SparseMatrix<double>::InnerIterator it(L,k);it;++it) { int row = it.row(); int col = it.col(); // std::sort for upper triangule matrix if(row <= col) { hessRowIdx.push_back(row); hessColIdx.push_back(col); } } } GTb = 0.5*G.transpose()*M*b; constantEnergyPart = b.transpose()*b; }
inline vcl_size_t size2(Eigen::SparseMatrix<T, options> & m) { return m.cols(); }