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; }
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(); }
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); }
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; } } }
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"); } }