int main_threshold(int argc, char* argv[]) { unsigned int flags = 0; enum th_type { NONE, WAV, LLR, DFW, MPDFW, HARD } th_type = NONE; int llrblk = 8; const struct opt_s opts[] = { OPT_SELECT('H', enum th_type, &th_type, HARD, "hard thresholding"), OPT_SELECT('W', enum th_type, &th_type, WAV, "daubechies wavelet soft-thresholding"), OPT_SELECT('L', enum th_type, &th_type, LLR, "locally low rank soft-thresholding"), OPT_SELECT('D', enum th_type, &th_type, DFW, "divergence-free wavelet soft-thresholding"), OPT_UINT('j', &flags, "bitmask", "joint soft-thresholding"), OPT_INT('b', &llrblk, "blocksize", "locally low rank block size"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); float lambda = atof(argv[1]); switch (th_type) { case WAV: wthresh(N, dims, lambda, flags, odata, idata); break; case LLR: lrthresh(N, dims, llrblk, lambda, flags, odata, idata); break; case DFW: dfthresh(N, dims, lambda, odata, idata); break; case HARD: hard_thresh(N, dims, lambda, odata, idata); break; default: md_zsoftthresh(N, dims, lambda, flags, odata, idata); } unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; }
int cc_compress(struct cc **output, struct cc **tokens, char flag) { struct cc **pp = tokens; struct cc *p = *pp++; int length = p->length; int threshold = thresh(length); #ifndef cc_weight short wthreshold = wthresh(length); #endif short *places = cc_places[length]; int *initial_scores = cc_initial_scores[length]; int initial_score0 = put_token_score(length); do { int score; struct cc_undo *undop; int ccount; #ifdef STATS int ncover; #endif int i; ccount = p->ccount; if ((short) ccount >= p->bcount) continue; if (p->code >= 0 || ccount >= threshold) score = 0; #ifndef cc_weight else if (p->weight >= wthreshold) /* allow one fewer match than normal */ /* XXX, should adjust for ccount */ score = - tt.tt_set_token_cost; #endif else score = initial_scores[ccount]; undop = cc_undo; #ifdef STATS ncover = 0; #endif for (i = p->places; i >= 0; i = places[i]) { struct cc **jp; struct cc *x; struct cc **ip = output + i; int score0 = initial_score0; struct cc **iip = ip + length; struct cc_undo *undop1 = undop; if ((x = *(jp = ip)) != 0) goto z; while (--jp >= output) if ((x = *jp) != 0) { if (jp + x->length > ip) goto z; break; } jp = ip + 1; while (jp < iip) { if ((x = *jp) == 0) { jp++; continue; } z: if (x == p) goto undo; #ifdef STATS ncover++; #endif undop->pos = jp; undop->val = x; undop++; *jp = 0; x->ccount--; score_adjust(score0, x); if (score0 < 0 && flag) goto undo; jp += x->length; } undop->pos = ip; undop->val = 0; undop++; *ip = p; ccount++; score += score0; continue; undo: while (--undop >= undop1) if ((*undop->pos = x = undop->val)) x->ccount++; undop++; } if (score > 0) { #ifdef STATS ccount_stat += ccount - p->ccount; ntoken_stat++; ncover_stat += ncover; #endif p->ccount = ccount; } else { struct cc_undo *u = cc_undo; while (--undop >= u) { struct cc *x; if ((*undop->pos = x = undop->val)) x->ccount++; } } } while ((p = *pp++) != 0); return pp - tokens; }
int cc_sweep(char *buffer, int bufsize, struct cc **tokens, int length) { struct cc *p; char *cp; int i; short *hc; short *places = cc_places[length]; struct cc **pp = tokens; short threshold = thresh(length); #ifndef cc_weight short wthreshold = wthresh(length); short limit = wlimit(length); #endif int time0; short pc = tt.tt_padc; i = length - 1; bufsize -= i; cp = buffer + i; hc = cc_hashcodes; time0 = cc_time0; for (i = 0; i < bufsize; i++, time0++) { struct cc **h; { short *hc1 = hc; short c = *cp++; short hh; if ((hh = *hc1) < 0 || c == pc) { *hc1++ = -1; hc = hc1; continue; } h = cc_htab + (*hc1++ = hash(hh, c)); hc = hc1; } for (p = *h; p != 0; p = p->hforw) if (p->length == (char) length) { char *p1 = p->string; char *p2 = cp - length; int n = length; do if (*p1++ != *p2++) goto fail; while (--n); break; fail: ; } if (p == 0) { p = cc_q1a.qback; if (p == &cc_q1a || (p->time >= cc_time0 && p->length == (char) length)) continue; if (p->hback != 0) if ((*p->hback = p->hforw) != 0) p->hforw->hback = p->hback; { char *p1 = p->string; char *p2 = cp - length; int n = length; do *p1++ = *p2++; while (--n); } p->length = length; #ifndef cc_weight p->weight = cc_weight; #endif p->time = time0; p->bcount = 1; p->ccount = 0; p->flag = 0; if ((p->hforw = *h) != 0) p->hforw->hback = &p->hforw; *h = p; p->hback = h; qinsert(p, &cc_q1a); places[i] = -1; p->places = i; #ifdef STATS ntoken_stat++; #endif } else if (p->time < cc_time0) { #ifndef cc_weight if ((p->weight += p->time - time0) < 0) p->weight = cc_weight; else if ((p->weight += cc_weight) > limit) p->weight = limit; #endif p->time = time0; p->bcount = 1; p->ccount = 0; if (p->code >= 0) { p->flag = 1; *pp++ = p; } else #ifndef cc_weight if (p->weight >= wthreshold) { p->flag = 1; *pp++ = p; qinsert(p, &cc_q1b); } else #endif { p->flag = 0; qinsert(p, &cc_q1a); } places[i] = -1; p->places = i; #ifdef STATS ntoken_stat++; #endif } else if (p->time + length > time0) { /* * overlapping token, don't count as two and * don't update time0, but do adjust weight to offset * the difference */ #ifndef cc_weight if (cc_weight != 0) { /* XXX */ p->weight += time0 - p->time; if (!p->flag && p->weight >= wthreshold) { p->flag = 1; *pp++ = p; qinsert(p, &cc_q1b); } } #endif places[i] = p->places; p->places = i; } else { #ifndef cc_weight if ((p->weight += p->time - time0) < 0) p->weight = cc_weight; else if ((p->weight += cc_weight) > limit) p->weight = limit; #endif p->time = time0; p->bcount++; if (!p->flag && /* code must be < 0 if flag false here */ (p->bcount >= threshold #ifndef cc_weight || p->weight >= wthreshold #endif )) { p->flag = 1; *pp++ = p; qinsert(p, &cc_q1b); } places[i] = p->places; p->places = i; } } if ((i = pp - tokens) > 0) { *pp = 0; if (cc_reverse) cc_sweep_reverse(tokens, places); if (cc_sort && i > 1) { qsort((char *) tokens, i, sizeof *tokens, cc_token_compare); } if (cc_chop) { if ((i = i * cc_chop / 100) == 0) i = 1; tokens[i] = 0; } i++; } return i; }