跳转至

代码

FDD 实现 — CPSD → 每频点 SVD → SV1 谱 → 左奇异向量振型

int tiny_sysid_fdd(const float *data, int n_ch, int n, float fs,
                   int fft_len, int n_modes, tiny_sysid_result_t *result)
{
    // ── Step 1: Welch 平均 CPSD 矩阵 ──
    int stride = n_ch * n_ch, n_bins;
    float *G = malloc((fft_len / 2) * stride * sizeof(float));
    tiny_sysid_cpsd_welch(data, n_ch, n, seg_len, fft_len, fs, G, &n_bins);

    // ── Step 2: 每频点 SVD(幂迭代求主奇异值/向量)──
    for (int k = 0; k < n_bins; k++) {
        float sigma;
        tiny_sysid_svd_dominant(G + k * stride, n_ch, &sigma, u);
        sv1_spectrum[k] = sigma;
        memcpy(mode_shapes + k * n_ch, u, n_ch * sizeof(float));
    }

    // ── Step 3: SV1 谱峰值检测 ──
    // 同 PP,但在 SV1 谱上而非平均 PSD 上
    tiny_sysid_find_peaks(sv1_spectrum, n_bins, n_modes, peak_bins, &n_found);

    // ── Step 4: 提取振型(SVD 左奇异向量)──
    for (int m = 0; m < n_found; m++) {
        int bin = peak_bins[m];
        result->frequencies[m] = tiny_sysid_bin_to_freq(bin, fft_len, fs);
        memcpy(result->shapes[m], mode_shapes + bin * n_ch, n_ch * sizeof(float));
        tiny_sysid_normalise_shape(result->shapes[m], n_ch);
    }
    tiny_sysid_dedup_modes(result, sv1_spectrum);
    result->success = 1;
    return 0;
}

FDD vs PP 核心区别

  • PP:auto-PSD → 平均 → sqrt(PSD) 振型
  • FDD:CPSD → SVD左奇异向量振型(SVD 自动降噪)