跳转至

代码

定位实现 — 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 损伤可能性