void CowichanSerial::winnow(IntMatrix matrix, BoolMatrix mask, PointVector points) { index_t r, c; index_t len; // number of points index_t stride; // selection stride index_t i, j; // count set cell len = mask_count (mask, nr, nc); if (len < n) { not_enough_points(); } WeightedPointVector weightedPoints = NULL; try { weightedPoints = NEW_VECTOR_SZ(WeightedPoint, len); } catch (...) {out_of_memory();} // fill temporary vector i = 0; for (r = 0; r < nr; r++) { for (c = 0; c < nc; c++) { if (MATRIX_RECT(mask, r, c)) { weightedPoints[i++] = WeightedPoint((real)c, (real)r, MATRIX_RECT(matrix, r, c)); } } } #ifdef SORT_TIME INT64 start, end; start = get_ticks (); #endif // sort std::sort(weightedPoints, &weightedPoints[len]); #ifdef SORT_TIME end = get_ticks (); #endif // copy over points stride = len / n; for (i = n - 1, j = len - 1; i >= 0; i--, j -= stride) { #ifdef WINNOW_OUTPUT std::cout << weightedPoints[j].weight << "\n"; #endif points[i] = weightedPoints[j].point; } #ifdef SORT_TIME std::cout << "winnow sort: "; print_elapsed_time(start, end); std::cout << std::endl; #endif delete [] weightedPoints; }
// weights are relative, i.e., they need not add up to n; a // typical choice of weights is each weight equals the reciprocal // of the variance of the measurement void add(double x, double y, double weight = 1.0) { INVARIANT(weight > 0, "weight should be > 0"); data.push_back(WeightedPoint(x, y, weight)); }