代码¶
定位实现 — COMAC 逐自由度 + 概率归一化
void tiny_damage_locate(const tiny_sysid_result_t *cur, tiny_damage_locate_t *out)
{
memset(out, 0, sizeof(*out));
out->dof = -1;
if (!g_has_baseline || !cur || cur->n_modes < 1) return;
int nch = cur->n_ch;
int nm = min(cur->n_modes, g_baseline.n_modes);
// ── 计算每个 DOF 的 COMAC ──
float comac[TINY_DAMAGE_MAX_DOF];
for (int d = 0; d < nch; d++) {
double num = 0, den_a = 0, den_b = 0;
for (int m = 0; m < nm; m++) {
float va = cur->shapes[m][d];
float vb = g_baseline.shapes[m][d];
num += (double)va * vb;
den_a += (double)va * va;
den_b += (double)vb * vb;
}
comac[d] = (den_a > 1e-30 && den_b > 1e-30)
? (float)(num * num / (den_a * den_b)) : 1.0f;
}
// ── 损伤概率 = 1 - COMAC,归一化至 [0, 1] ──
float pmax = 0;
for (int d = 0; d < nch; d++) {
float p = 1.0f - comac[d];
out->prob[d] = p;
if (p > pmax) pmax = p;
}
if (pmax > 1e-12f)
for (int d = 0; d < nch; d++) out->prob[d] /= pmax;
// ── 选择概率最高的 DOF ──
int best = 0;
for (int d = 1; d < nch; d++)
if (out->prob[d] > out->prob[best]) best = d;
out->dof = best;
// ── 记录最低 COMAC ──
float cmin = 1.0f;
for (int d = 0; d < nch; d++)
if (comac[d] < cmin) cmin = comac[d];
out->comac_min = cmin;
}
关键逻辑:
- COMAC 逐 DOF 跨模态累加计算,类似 MAC 但对每个自由度独立
- 用 double 累加避免浮点精度损失
- 概率归一化后最高值 = DOF 损伤可能性