Пример #1
0
MarkedBlock::Handle* BlockDirectory::tryAllocateBlock()
{
    SuperSamplerScope superSamplerScope(false);
    
    MarkedBlock::Handle* handle = MarkedBlock::tryCreate(*m_heap, subspace()->alignedMemoryAllocator());
    if (!handle)
        return nullptr;
    
    markedSpace().didAddBlock(handle);
    
    return handle;
}
Пример #2
0
void BlockDirectory::removeBlock(MarkedBlock::Handle* block)
{
    ASSERT(block->directory() == this);
    ASSERT(m_blocks[block->index()] == block);
    
    subspace()->didRemoveBlock(block->index());
    
    m_blocks[block->index()] = nullptr;
    m_freeBlockIndices.append(block->index());
    
    forEachBitVector(
        holdLock(m_bitvectorLock),
        [&] (FastBitVector& vector) {
            vector[block->index()] = false;
        });
    
    block->didRemoveFromDirectory();
}
Пример #3
0
void BlockDirectory::addBlock(MarkedBlock::Handle* block)
{
    size_t index;
    if (m_freeBlockIndices.isEmpty()) {
        index = m_blocks.size();

        size_t oldCapacity = m_blocks.capacity();
        m_blocks.append(block);
        if (m_blocks.capacity() != oldCapacity) {
            forEachBitVector(
                NoLockingNecessary,
                [&] (FastBitVector& vector) {
                    ASSERT_UNUSED(vector, vector.numBits() == oldCapacity);
                });
            
            ASSERT(m_blocks.capacity() > oldCapacity);
            
            LockHolder locker(m_bitvectorLock);
            subspace()->didResizeBits(m_blocks.capacity());
            forEachBitVector(
                locker,
                [&] (FastBitVector& vector) {
                    vector.resize(m_blocks.capacity());
                });
        }
    } else {
        index = m_freeBlockIndices.takeLast();
        ASSERT(!m_blocks[index]);
        m_blocks[index] = block;
    }
    
    forEachBitVector(
        NoLockingNecessary,
        [&] (FastBitVector& vector) {
            ASSERT_UNUSED(vector, !vector[index]);
        });

    // This is the point at which the block learns of its cellSize() and attributes().
    block->didAddToDirectory(this, index);
    
    setIsLive(NoLockingNecessary, index, true);
    setIsEmpty(NoLockingNecessary, index, true);
}
Пример #4
0
void GRASTA_training(const mat &D,
        mat &Uhat,
        struct STATUS &status,
        const struct GRASTA_OPT &options,
        mat &W,
        mat &Outlier
        )
{
    int rows, cols;
    rows = D.n_rows; cols = D.n_cols;
    
    if ( !status.init ){
        status.init         = 1;
        status.curr_iter    = 0;
        
        status.last_mu      = options.MIN_MU;
        status.level        = 0;
        status.step_scale   = 0.0;
        status.last_w       = zeros(options.RANK, 1);
        status.last_gamma   = zeros(options.DIM, 1);        
        
        if (!Uhat.is_finite()){
            Uhat = orth(randn(options.DIM, options.RANK));        
        }
    }
    
    Outlier      = zeros<mat>(rows, cols);
    W            = zeros<mat>(options.RANK, cols);
    
    mat         U_Omega, y_Omega, y_t, s, w, dual, gt;
    uvec        idx, col_order;
    ADMM_OPT    admm_opt;
    double      SCALE, t, rel;
    bool        bRet;
    
    admm_opt.lambda = options.lambda;
    //if (!options.QUIET) 
    int maxIter = options.maxCycles * cols; // 20 passes through the data set
    status.hist_rel.reserve( maxIter);
                
    // Order of examples to process
    arma_rng::set_seed_random();
    col_order = conv_to<uvec>::from(floor(cols*randu(maxIter, 1)));
    
    for (int k=0; k<maxIter; k++){
        int iCol = col_order(k);
        //PRINTF("%d / %d\n",iCol, cols);
        
        y_t     = D.col(iCol);
        idx     = find_finite(y_t);
                
        y_Omega = y_t.elem(idx);
        
        SCALE = norm(y_Omega);
        y_Omega = y_Omega/SCALE;
        
        // the following for-loop is for U_Omega = U(idx,:) in matlab
        U_Omega = zeros<mat>(idx.n_elem, Uhat.n_cols);
        for (int i=0; i<idx.n_elem; i++)
            U_Omega.row(i) = Uhat.row(idx(i));
        
        // solve L-1 regression
        admm_opt.MAX_ITER = options.MAX_ITER;
        
        if (options.NORM_TYPE == L1_NORM)
            bRet = ADMM_L1(U_Omega, y_Omega, admm_opt, s, w, dual);
        else if (options.NORM_TYPE == L21_NORM){
            w = solve(U_Omega, y_Omega);
            s = y_Omega - U_Omega*w;
            dual = -s/norm(s, 2);
        }
        else {
            PRINTF("Error: norm type does not support!\n");
            return;
        }
        
        vec tmp_col = zeros<vec>(rows);
        tmp_col.elem(idx) = SCALE * s;
        
        Outlier.col(iCol) = tmp_col;
        
        W.col(iCol) =  SCALE * w;

        // take gradient step over Grassmannian
        t = GRASTA_update(Uhat, status, w, dual, idx, options);
        
        if (!options.QUIET){
            rel = subspace(options.GT_mat, Uhat);
            status.hist_rel.push_back(rel);
            
            if (rel < options.TOL){
                PRINTF("%d/%d: subspace angle %.2e\n",k,maxIter, rel);
                break;
            }
        }
        
        if (k % cols ==0){
            
            if (!options.QUIET) PRINTF("Pass %d/%d: step-size %.2e, level %d, last mu %.2f\n",
                    k % cols, options.maxCycles, t, status.level, status.last_mu);
        }
        if (status.level >= options.convergeLevel){
            // Must cycling around the dataset twice to get the correct regression weight W
            if (!options.QUIET) PRINTF("Converge at level %d, last mu %.2f\n",status.level,status.last_mu);           
            break;
        }        
    }
}
Пример #5
0
void DimensionReduction::apply(Window im, int dimensions) {
    assert(dimensions < im.channels && dimensions > 0, 
           "dimensions must be greater than zero and less than the current number of channels\n");

    // get some statistics (mostly for the covariance matrix)
    Stats stats(im);

    // we're going to find the leading eigenvectors of the covariance matrix and
    // use them as the basis for our subspace
    vector<float> subspace(dimensions * im.channels), newsubspace(dimensions * im.channels);

    for (int i = 0; i < dimensions * im.channels; i++) subspace[i] = randomFloat(0, 1);

    float delta = 1;
    while (delta > 0.00001) {
        // multiply the subspace by the covariance matrix
        for (int d = 0; d < dimensions; d++) {
            for (int c1 = 0; c1 < im.channels; c1++) {
                newsubspace[d * im.channels + c1] = 0;
                for (int c2 = 0; c2 < im.channels; c2++) {
                    newsubspace[d * im.channels + c1] += (float)(subspace[d * im.channels + c2] * stats.covariance(c1, c2));
                }
            }
        }

        // orthonormalize it with gram-schmidt
        for (int d = 0; d < dimensions; d++) {
            // first subtract it's component in the direction of all earlier vectors
            for (int d2 = 0; d2 < d; d2++) {
                float dot = 0;
                for (int c = 0; c < im.channels; c++) {
                    dot += newsubspace[d * im.channels + c] * newsubspace[d2 * im.channels + c];
                }
                for (int c = 0; c < im.channels; c++) {
                    newsubspace[d * im.channels + c] -= dot * newsubspace[d2 * im.channels + c];
                }                
            }
            // then normalize it
            float sum = 0;
            for (int c = 0; c < im.channels; c++) {
                float val = newsubspace[d * im.channels + c];
                sum += val * val;
            }
            float factor = 1.0f / sqrt(sum);
            for (int c = 0; c < im.channels; c++) {
                newsubspace[d * im.channels + c] *= factor;
            }
            // if the sum is negative, flip it
            sum = 0;
            for (int c = 0; c < im.channels; c++) {
                sum += newsubspace[d * im.channels + c];
            }
            if (sum < -0.01) {
                for (int c = 0; c < im.channels; c++) {
                    newsubspace[d * im.channels + c] *= -1;
                }                
            }
        }

        // check to see how much changed
        delta = 0;
        for (int d = 0; d < dimensions; d++) {
            for (int c = 0; c < im.channels; c++) {
                float diff = newsubspace[d * im.channels + c] - subspace[d * im.channels + c];
                delta += diff * diff;
            }
        }

        newsubspace.swap(subspace);
    }

    // now project the image onto the subspace

    vector<float> output(im.channels);
    for (int t = 0; t < im.frames; t++) {
        for (int y = 0; y < im.height; y++) {
            for (int x = 0; x < im.width; x++) {
                for (int c = 0; c < im.channels; c++) output[c] = 0;
                // project this pixel onto each vector, and add the results
                for (int d = 0; d < dimensions; d++) {
                    float dot = 0;
                    for (int c = 0; c < im.channels; c++) {
                        dot += im(x, y, t)[c] * subspace[d * im.channels + c];                        
                    }
                    for (int c = 0; c < im.channels; c++) {
                        output[c] += dot * subspace[d * im.channels + c];
                    }
                }
                for (int c = 0; c < im.channels; c++) im(x, y, t)[c] = output[c];
            }
        }
    }

    // display the subspace for debugging
    printf("Basis chosen:\n");
    for (int c = 0; c < im.channels; c++) {
        for (int d = 0; d < dimensions; d++) {
            printf("%f \t", newsubspace[d * im.channels + c]);
        }
        printf("\n");
    }        



}