Skip to content

Commit 47dccf4

Browse files
committed
processor_tda: Make threshold configurable
Expose threshold as a quantile-based distance scale selector. Signed-off-by: Hiroshi Hatake <[email protected]>
1 parent 8e5d12c commit 47dccf4

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

plugins/processor_tda/tda.c

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ static int cmp_float_asc(const void *a, const void *b)
5252
}
5353
}
5454

55-
static float tda_choose_threshold_from_dist(const float *dist,
55+
static float tda_choose_threshold_from_dist(struct tda_proc_ctx *ctx,
56+
const float *dist,
5657
size_t n,
5758
double quantile)
5859
{
@@ -64,16 +65,27 @@ static float tda_choose_threshold_from_dist(const float *dist,
6465
size_t k = 0;
6566
float thr = 0.0f;
6667
double pos;
68+
double q;
6769

6870
if (!dist || n < 2) {
6971
return 0.0f;
7072
}
7173

72-
if (quantile <= 0.0) {
73-
quantile = 0.0;
74+
/* if user specified threshold as quantile (0 < q < 1),
75+
* override the default quantile argument.
76+
*/
77+
if (ctx && ctx->threshold > 0.0 && ctx->threshold < 1.0) {
78+
q = ctx->threshold;
7479
}
75-
else if (quantile >= 1.0) {
76-
quantile = 1.0;
80+
else {
81+
q = quantile;
82+
}
83+
84+
if (q <= 0.0) {
85+
q = 0.0;
86+
}
87+
else if (q >= 1.0) {
88+
q = 1.0;
7789
}
7890

7991
/* number of unique off-diagonal distances */
@@ -107,7 +119,7 @@ static float tda_choose_threshold_from_dist(const float *dist,
107119
idx = 0;
108120
}
109121
else {
110-
pos = quantile * (double) (k - 1);
122+
pos = q * (double) (k - 1);
111123
if (pos < 0.0) {
112124
pos = 0.0;
113125
}
@@ -120,7 +132,7 @@ static float tda_choose_threshold_from_dist(const float *dist,
120132
thr = vals[idx];
121133

122134
flb_debug("[tda] chosen distance threshold=%.6f (quantile=%.2f, m=%zu)",
123-
thr, quantile, k);
135+
thr, q, k);
124136

125137
flb_free(vals);
126138

@@ -914,19 +926,18 @@ static void tda_window_run_ripser(struct tda_window *w,
914926
/* --- choose a scale for TDA ---
915927
* Use the number of embedded points n_embed to determine the threshold.
916928
*/
917-
threshold = tda_choose_threshold_from_dist(dist, n_embed, q);
929+
threshold = tda_choose_threshold_from_dist(ctx, dist, n_embed, q);
918930
if (threshold <= 0.0f) {
919931
threshold = 0.0f;
920932
}
921-
threshold = 0.0f;
922933

923934
memset(&betti, 0, sizeof(betti));
924935

925936
nq = sizeof(q_candidates) / sizeof(q_candidates[0]);
926937

927938
for (qi = 0; qi < nq; qi++) {
928939
qc = q_candidates[qi];
929-
thr = tda_choose_threshold_from_dist(dist, n_embed, qc);
940+
thr = tda_choose_threshold_from_dist(ctx, dist, n_embed, qc);
930941

931942
if (thr < 0.0f) {
932943
thr = 0.0f;
@@ -950,13 +961,28 @@ static void tda_window_run_ripser(struct tda_window *w,
950961
best_b1 = tmp.betti[1];
951962
best_b0 = tmp.betti[0];
952963
best_b2 = (tmp.num_dims > 2) ? tmp.betti[2] : 0;
953-
best_q_for_b1 = q;
964+
965+
/* if user forced ctx->threshold as quantile, report that,
966+
* otherwise report the candidate quantile qc.
967+
*/
968+
if (ctx && ctx->threshold > 0.0 && ctx->threshold < 1.0) {
969+
best_q_for_b1 = ctx->threshold;
970+
}
971+
else {
972+
best_q_for_b1 = qc;
973+
}
954974
}
955975
/* If all H1 are zero, fall back to H0. */
956976
else if (best_b1 == 0 && tmp.betti[0] > best_b0) {
957977
best_b0 = tmp.betti[0];
958978
best_b2 = (tmp.num_dims > 2) ? tmp.betti[2] : 0;
959-
best_q_for_b1 = q;
979+
980+
if (ctx && ctx->threshold > 0.0 && ctx->threshold < 1.0) {
981+
best_q_for_b1 = ctx->threshold;
982+
}
983+
else {
984+
best_q_for_b1 = qc;
985+
}
960986
}
961987
}
962988

@@ -1177,6 +1203,12 @@ static struct flb_config_map config_map[] = {
11771203
0, FLB_TRUE, offsetof(struct tda_proc_ctx, embed_delay),
11781204
"Delay embedding lag tau in samples. This means that 1 delaying sample."
11791205
},
1206+
{
1207+
FLB_CONFIG_MAP_DOUBLE, "threshold", "0",
1208+
0, FLB_TRUE, offsetof(struct tda_proc_ctx, threshold),
1209+
"Distance scale selector. 0 = auto multi-quantile scan; "
1210+
"(0,1) = use as quantile to pick the distance threshold."
1211+
},
11801212
/* EOF */
11811213
{0}
11821214
};

plugins/processor_tda/tda.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct tda_proc_ctx {
6060
/* delay embedding parameters */
6161
int embed_dim; /* m: number of delays (1 = no embedding) */
6262
int embed_delay; /* tau: delay in samples */
63+
double threshold;
6364

6465
/* exposed betti-number gauges (created lazily) */
6566
struct cmt_gauge *g_betti0;

0 commit comments

Comments
 (0)