Skip to content

CODE

FDD Implementation — CPSD → Per-Bin SVD → SV1 Spectrum → Left Singular Vectors

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)
{
    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);

    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));
    }

    tiny_sysid_find_peaks(sv1_spectrum, n_bins, n_modes, peak_bins, &n_found);

    for (int m = 0; m < n_found; m++) {
        result->frequencies[m] = tiny_sysid_bin_to_freq(peak_bins[m], fft_len, fs);
        memcpy(result->shapes[m], mode_shapes + peak_bins[m] * n_ch, ...);
        tiny_sysid_normalise_shape(result->shapes[m], n_ch);
    }
    tiny_sysid_dedup_modes(result, sv1_spectrum);
    result->success = 1;
    return 0;
}