You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

钟形条件信号频谱的非均匀频率区间离散化算法优化及简洁实现方案问询

Streamlined Non-Uniform Frequency Sampling for Bell-Shaped Spectra

Got it, let's fix that clunky code—you want a way to generate frequency samples that cluster tightly around your peak f_max without all the manual band splits and extra parameters. Here's a clean, low-input approach using a sigmoid-based nonlinear mapping that works in both Python and MATLAB, and lets you control sample density with just a handful of key values.

Core Idea

Instead of splitting your frequency range into arbitrary bands, we use a sigmoid function to warp uniform [0,1] samples into your target frequency interval. This naturally clusters samples around f_max, and you can adjust a single "sharpness" parameter to control how tight that clustering is. No more defining separate sample counts for pre-peak, peak, and post-peak regions—just set a total number of samples.

Python Implementation

import numpy as np
import matplotlib.pyplot as plt

def generate_nonuniform_freq(f_start, f_end, f_max, total_samples, sharpness=5):
    # Normalize peak frequency to a [0,1] range relative to your bounds
    max_norm = (f_max - f_start) / (f_end - f_start)
    # Generate evenly spaced points between 0 and 1
    x = np.linspace(0, 1, total_samples)
    # Sigmoid mapping to cluster points around the normalized peak
    # Higher sharpness = more samples concentrated near f_max
    sigmoid_x = 1 / (1 + np.exp(-sharpness * (x - max_norm)))
    # Map back to your original frequency range
    freq = f_start + (f_end - f_start) * sigmoid_x
    # Calculate frequency steps for downstream use
    df = np.diff(freq)
    return freq, df

# Example usage (matches your original parameters)
f_start = 0.016
f_end = 1.25
f_max = 0.16
total_samples = 50  # Total points you want (replace your N array)
sharpness = 8       # Crank this up for tighter clustering around f_max

freq, df = generate_nonuniform_freq(f_start, f_end, f_max, total_samples, sharpness)

# Plot full range
plt.figure(figsize=(10, 4))
plt.plot(freq, np.ones_like(freq), 'b-o', markersize=4, linewidth=1.5)
plt.scatter([f_start, f_max, f_end], [1, 1, 1], c='red', s=60, zorder=5)
plt.xlabel('Frequency (Hz)')
plt.title('Non-Uniform Frequency Samples Clustered at Peak')
plt.grid(True, alpha=0.5)
plt.show()

# Plot zoomed view near peak
plt.figure(figsize=(10, 4))
plt.plot(freq, np.ones_like(freq), 'b-o', markersize=4, linewidth=1.5)
plt.scatter([f_start, f_max, f_end], [1, 1, 1], c='red', s=60, zorder=5)
plt.xlabel('Frequency (Hz)')
plt.title('Zoomed View Near Peak')
plt.grid(True, alpha=0.5)
plt.xlim(0, 0.4)
plt.show()

MATLAB Implementation

function [freq, df] = generate_nonuniform_freq(f_start, f_end, f_max, total_samples, sharpness)
    % Set default sharpness if not provided
    if nargin < 5
        sharpness = 5;
    end
    % Normalize peak to [0,1] relative to frequency bounds
    max_norm = (f_max - f_start) / (f_end - f_start);
    % Generate uniform [0,1] samples
    x = linspace(0, 1, total_samples);
    % Sigmoid mapping to cluster samples around peak
    sigmoid_x = 1 ./ (1 + exp(-sharpness * (x - max_norm)));
    % Map back to original frequency range
    freq = f_start + (f_end - f_start) * sigmoid_x;
    % Calculate frequency steps
    df = diff(freq);
end

% Example usage
f_start = 0.016;
f_end = 1.25;
f_max = 0.16;
total_samples = 50;
sharpness = 8;

[freq, df] = generate_nonuniform_freq(f_start, f_end, f_max, total_samples, sharpness);

% Full range plot
figure('Position', [100, 100, 800, 320])
plot(freq, ones(size(freq)), 'b-o', 'MarkerSize', 4, 'LineWidth', 1.5)
hold on
scatter([f_start, f_max, f_end], [1,1,1], 60, 'r', 'filled', 'ZOrder', 5)
xlabel('Frequency (Hz)')
title('Non-Uniform Frequency Samples Clustered at Peak')
grid on
alpha(0.5)
hold off

% Zoomed peak plot
figure('Position', [100, 100, 800, 320])
plot(freq, ones(size(freq)), 'b-o', 'MarkerSize', 4, 'LineWidth', 1.5)
hold on
scatter([f_start, f_max, f_end], [1,1,1], 60, 'r', 'filled', 'ZOrder', 5)
xlabel('Frequency (Hz)')
title('Zoomed View Near Peak')
grid on
alpha(0.5)
xlim([0, 0.4])
hold off

Why This Works Better

  • Minimal inputs: Only need f_start, f_end, f_max, total samples, and optional sharpness. No more manual band splits or multiple sample count parameters.
  • Smooth transitions: Unlike your original code's hard band edges, samples shift gradually from sparse (far from peak) to dense (near peak), which aligns better with a bell-shaped spectrum's energy distribution.
  • Flexible control: Adjust sharpness to fine-tune density:
    • Lower values (2-5): More spread-out samples, closer to uniform
    • Higher values (8-15): Tighter clustering around f_max

Alternative: Log-Based Clustering

If you need even sparser samples in the low/high frequency tails (common for some bell-shaped spectra), you can combine the sigmoid mapping with a log transformation. Here's a Python variant:

def generate_log_clustered_freq(f_start, f_end, f_max, total_samples, stretch=2):
    # Small shift to avoid log(0) issues
    shift = f_start * 1.1
    f_start_shifted = f_start + shift
    f_end_shifted = f_end + shift
    f_max_shifted = f_max + shift
    
    # Normalize peak in log space
    max_log_norm = (np.log(f_max_shifted) - np.log(f_start_shifted)) / (np.log(f_end_shifted) - np.log(f_start_shifted))
    x = np.linspace(0, 1, total_samples)
    # Sigmoid cluster around log-space peak
    sigmoid_x = 1 / (1 + np.exp(-stretch * (x - max_log_norm)))
    # Map back to linear frequency space
    log_freq = np.log(f_start_shifted) + sigmoid_x * (np.log(f_end_shifted) - np.log(f_start_shifted))
    freq = np.exp(log_freq) - shift
    df = np.diff(freq)
    return freq, df

内容的提问来源于stack exchange,提问作者Varga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 10:53:11