//----------------------------------------------------------------------------- void RandomPassiveSet(BitMatrix& passive_set, Random& rng, const unsigned int height, const unsigned int width) { passive_set.Resize(height, width); unsigned int* buf_ps = passive_set.Buffer(); const unsigned int ldim = passive_set.LDim(); const unsigned int full_wds = height / BitMatrix::BITS_PER_WORD; const unsigned int extra = height - BitMatrix::BITS_PER_WORD*full_wds; const unsigned int MASK = passive_set.Mask(); // initial nonzero bit pattern to fill columns with unsigned int pattern = 0x01; // randomly shuffle the column indices of the passive set std::vector<unsigned int> col_indices(width); for (unsigned int q=0; q<width; ++q) col_indices[q] = q; if (width > 1) FisherYatesShuffle(col_indices.begin(), col_indices.end(), rng); for (unsigned int c=0; c<width; ++c) { unsigned int col_index = col_indices[c]; unsigned int col_offset = col_index * ldim; // Fill this column with the bit pattern, ensuring that the // final bits in each column (outside the MASK for the passive // set matrix) are zero. unsigned int r_wd=0; for (; r_wd < full_wds; ++r_wd) buf_ps[col_offset + r_wd] = pattern; if (extra > 0) { unsigned int wd = MASK & pattern; assert(wd > 0); buf_ps[col_offset + r_wd] = wd; } // shift the pattern to the left one bit and OR in a new bit pattern <<= 1; pattern |= 1; // start over if all ones if (0xFFFFFFFF == pattern) pattern = 0x01; } // None of the columns should contain all zero bits. std::vector<unsigned int> col_sums(width); passive_set.SumColumns(col_sums); for (unsigned int c=0; c<width; ++c) { if (0 == col_sums[c]) { unsigned int col_offset = c*ldim; cout << "RandomPassiveSet: column " << c << " is a zero column." << endl; cout << "Pattern: " << std::hex << pattern << std::dec << endl; cout << "Height: " << height << ", width: " << width << endl; cout << "full_wds: " << full_wds << endl; cout << "extra: " << extra << endl; cout << "Ldim: " << ldim << ", extra: " << extra << endl; cout << "MASK: " << std::hex << MASK << std::dec << endl; cout << "col_offset: " << col_offset << endl; unsigned int r_wd = 0; for (; r_wd<full_wds; ++r_wd) cout << "words_[" << r_wd << "]: " << std::hex << buf_ps[col_offset + r_wd] << std::dec << endl; if (MASK > 0) { unsigned int wd = MASK & buf_ps[col_offset + r_wd]; cout << "words_[" << r_wd << "]: " << std::hex << wd << std::dec << endl; } assert(0 != col_sums[c]); } } }
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]; } } }