예제 #1
0
파일: test_bpp.cpp 프로젝트: beckgom/smallk
//-----------------------------------------------------------------------------
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]);
        }
    }
}
예제 #2
0
파일: nnls.hpp 프로젝트: beckgom/smallk
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];
        }
    }
}