void TopTerms(const int maxterms, const DenseMatrix<T>& V, // column vector (single col of W) std::vector<int>& sort_indices, std::vector<int>& term_indices) { // Sort the row indices for topic vector V into decreasing order. // Compare data elements to rearrange the indices. int height = V.Height(); if (sort_indices.size() < static_cast<unsigned int>(height)) throw std::runtime_error("TopTerms: index array too small"); if (term_indices.size() < static_cast<unsigned int>(maxterms)) throw std::runtime_error("TopTerms: term array too small"); const T* data = V.LockedBuffer(); // initialize the indices for the sort for (int q=0; q<height; ++q) sort_indices[q] = q; std::sort(&sort_indices[0], &sort_indices[0] + height, [&data](int i1, int i2) {return data[i1] > data[i2];}); size_t max_terms = std::min(maxterms, height); for (size_t q=0; q<max_terms; ++q) { int index = sort_indices[q]; assert(index >= 0); assert(index < height); term_indices[q] = index; } }
void OverwriteCols(DenseMatrix<T>& A, const DenseMatrix<T>& B, const std::vector<unsigned int>& col_indices, const unsigned int num_cols) { const unsigned int height = A.Height(); // Overwrite columns of A with B. if (B.Height() != A.Height()) throw std::logic_error("OverwriteCols: height mismatch"); if (num_cols > static_cast<unsigned int>(A.Width())) throw std::logic_error("OverwriteCols: col indices out of bounds"); T* buf_a = A.Buffer(); const unsigned int ldim_a = A.LDim(); const T* buf_b = B.LockedBuffer(); const unsigned int ldim_b = B.LDim(); for (unsigned int c=0; c<num_cols; ++c) { unsigned int col_a = col_indices[c]; unsigned int offset_a = col_a*ldim_a; unsigned int offset_b = c*ldim_b; memcpy(&buf_a[offset_a], &buf_b[offset_b], height * sizeof(T)); } }
void Overwrite(DenseMatrix<T>& A, const DenseMatrix<T>& B, const std::vector<unsigned int>& row_indices, const std::vector<unsigned int>& col_indices, const unsigned int num_rows, const unsigned int num_cols) { // Overwrite entries in A with entries in B. The row and column // index arrays contain the destination indices to be overwritten. // Matrix B has size num_rows x num_cols. if (num_rows > static_cast<unsigned int>(A.Height())) throw std::logic_error("Overwrite: row indices out of bounds"); if (num_cols > static_cast<unsigned int>(A.Width())) throw std::logic_error("Overwrite: col indices out of bounds"); const T* buf_b = B.LockedBuffer(); const unsigned int ldim_b = B.LDim(); T* buf_a = A.Buffer(); const unsigned int ldim_a = A.LDim(); for (unsigned int c=0; c<num_cols; ++c) { unsigned int col_a = col_indices[c]; unsigned int offset_a = ldim_a * col_a; unsigned int offset_b = ldim_b * c; for (unsigned int r=0; r<num_rows; ++r) { unsigned int row_a = row_indices[r]; //T val = B.Get(r, c); //A.Set(row_a, col_a, val); buf_a[offset_a + row_a] = buf_b[offset_b + r]; } } }
void BppUpdateSets(BitMatrix& nonopt_set, BitMatrix& infeas_set, const BitMatrix& not_opt_mask, const DenseMatrix<T>& X, const DenseMatrix<T>& Y, const BitMatrix& passive_set) { // This function performs the equivalent of these operations: // // nonopt_set = not_opt_mask & (Y < T(0)) & ~passive_set; // infeas_set = not_opt_mask & (X < T(0)) & passive_set; const unsigned int height = not_opt_mask.Height(); const unsigned int width = not_opt_mask.Width(); if ( (static_cast<unsigned int>(X.Height()) != height) || (static_cast<unsigned int>(Y.Height()) != height) || (passive_set.Height() != height)) throw std::logic_error("BppUpdateSets: height mismatch"); if ( (static_cast<unsigned int>(X.Width()) != width) || (static_cast<unsigned int>(Y.Width()) != width) || (passive_set.Width() != width)) throw std::logic_error("BppUpdateSets: width mismatch"); nonopt_set.Resize(height, width); infeas_set.Resize(height, width); const unsigned int BITS = BitMatrix::BITS_PER_WORD; const unsigned int MASK = nonopt_set.Mask(); assert(infeas_set.Mask() == MASK); unsigned int* buf_r = nonopt_set.Buffer(); const unsigned int ldim_r = nonopt_set.LDim(); unsigned int* buf_i = infeas_set.Buffer(); const unsigned int ldim_i = infeas_set.LDim(); const unsigned int* buf_m = not_opt_mask.LockedBuffer(); const unsigned int ldim_m = not_opt_mask.LDim(); const T* buf_x = X.LockedBuffer(); const unsigned int ldim_x = X.LDim(); const T* buf_y = Y.LockedBuffer(); const unsigned int ldim_y = Y.LDim(); const unsigned int* buf_p = passive_set.LockedBuffer(); const unsigned int ldim_p = passive_set.LDim(); const unsigned int full_wds = height / BITS; const unsigned int extra = height - BITS*full_wds; assert(ldim_r >= ldim_m); assert(ldim_r >= ldim_p); OPENMP_PRAGMA(omp parallel for) for (unsigned int c=0; c<width; ++c) { unsigned int offset_r = c*ldim_r; unsigned int offset_i = c*ldim_i; unsigned int offset_m = c*ldim_m; unsigned int offset_x = c*ldim_x; unsigned int offset_y = c*ldim_y; unsigned int offset_p = c*ldim_p; unsigned int r_wd = 0, r=0; for (; r_wd<full_wds; ++r_wd) { unsigned int x_wd = 0, y_wd = 0; for (unsigned int q=0; q<BITS; ++q, ++r) { if (buf_x[offset_x + r] < T(0)) x_wd |= (1 << q); if (buf_y[offset_y + r] < T(0)) y_wd |= (1 << q); } buf_r[offset_r + r_wd] = buf_m[offset_m + r_wd] & y_wd & ~buf_p[offset_p + r_wd]; buf_i[offset_i + r_wd] = buf_m[offset_m + r_wd] & x_wd & buf_p[offset_p + r_wd]; } if (extra > 0) { unsigned int x_wd = 0, y_wd = 0; for (unsigned int q=0; q<extra; ++q, ++r) { if (buf_x[offset_x + r] < T(0)) x_wd |= (1 << q); if (buf_y[offset_y + r] < T(0)) y_wd |= (1 << q); } buf_r[offset_r + r_wd] = MASK & buf_m[offset_m + r_wd] & y_wd & ~buf_p[offset_p + r_wd]; buf_i[offset_i + r_wd] = MASK & buf_m[offset_m + r_wd] & x_wd & buf_p[offset_p + r_wd]; } } }