/* multiplication between sparse and classic matrix A=D*Q * hists: sparse matrix (typically matrix of database words) * nhist: matrix (typically matrix of query words) * return: hists*nhists (matrix) */ Mat mul(const SparseMat &hists, const Mat &nhist) { Mat answer = Mat::zeros(hists.size(0),1,CV_32F); SparseMatConstIterator it = hists.begin(), it_end = hists.end(); for (; it!=it_end;++it) { const SparseMat::Node* n = it.node(); answer.at<float>(n->idx[0])+=nhist.at<float>(n->idx[1])*it.value<float>(); } return answer; }
SparseMatRowConstIterator::SparseMatRowConstIterator( const SparseMatConstIterator &smi) : mat(smi.mat), row_(smi.row()), coliter(smi.coliter) { }
void CmShow::showTinySparseMat(CStr &title, const SparseMat &A1d) { int N = A1d.nzcount(); if (N > 1000) return; struct NodeSM { int r, c; double v; bool operator < (const NodeSM &n) { if (r < n.r) return true; else if (r > n.r) return false; else return c < n.c; } void print() { if (abs(v) > 1e-8) printf("(%d, %d) %-12g\t", r, c, v); } }; vector<NodeSM> nodes(N); SparseMatConstIterator it = A1d.begin(); for (int i = 0; i < N; i++, ++it) { const int* idx = it.node()->idx; nodes[i].r = idx[0] + 1; nodes[i].c = idx[1] + 1; nodes[i].v = it.value<double>(); } sort(nodes.begin(), nodes.end()); for (int i = 0; i < N; i++) nodes[i].print(); printf("\n"); Mat m; A1d.convertTo(m, CV_64F); showTinyMat(title, m); }
/** * Convert float cv::SparseMat to MxArray * @param mat cv::SparseMat object * @return MxArray object */ MxArray::MxArray(const cv::SparseMat& mat) { if (mat.dims() != 2) mexErrMsgIdAndTxt("mexopencv:error","cv::Mat is not 2D"); if (mat.type() != CV_32FC1) mexErrMsgIdAndTxt("mexopencv:error","cv::Mat is not float"); // Create sparse array int m = mat.size(0), n = mat.size(1), nnz = mat.nzcount(); p_ = mxCreateSparse(m, n, nnz, mxREAL); if (!p_) mexErrMsgIdAndTxt("mexopencv:error","Allocation error"); mwIndex *ir = mxGetIr(p_); mwIndex *jc = mxGetJc(p_); if (ir==NULL || jc==NULL) mexErrMsgIdAndTxt("mexopencv:error","Unknown error"); // Sort nodes before we put elems into mxArray vector<const SparseMat::Node*> nodes; nodes.reserve(nnz); for (SparseMatConstIterator it = mat.begin(); it != mat.end(); ++it) nodes.push_back(it.node()); sort(nodes.begin(),nodes.end(),compareSparseMatNode); // Copy data double *pr = mxGetPr(p_); int i = 0; jc[0] = 0; for (vector<const SparseMat::Node*>::const_iterator it = nodes.begin(); it != nodes.end(); ++it) { mwIndex row = (*it)->idx[0], col = (*it)->idx[1]; ir[i] = row; jc[col+1] = i+1; pr[i] = static_cast<double>(mat.value<float>(*it)); ++i; } }