函数组:SDIF

DDIF命令详解

一般格式:    "DDIF_" + [] "_ACTIVATE/GET/INPUT"

 

DOMA:
DTEL:数据元素
ENQU:锁对象
INDX:索引
SHLP:外键
TABL:表格
TABT:技术设置
TTYP:表格类型
VIET:视图技术设置
VIEW:视图

 

特殊:

DDIF_NAMETAB_GET获取运行对象
DDIF_STATE_GET确定对象状态
DDIF_OBJECT_DELETE删除对象
DDIF_OBJECT_RESET重置对象
DDIF_TYPEINFO_GET
获取类型信息
function radar_signal_sorting_gui() % 雷达信号分选算法主界面 % 创建一个GUI界面,让用户选择使用SDIF或CDIF算法进行信号分选 % 创建主选择界面 mainFig = figure('Name', '雷达信号分选算法', 'NumberTitle', 'off', ... 'Position', [300, 200, 400, 250], 'MenuBar', 'none', ... 'Resize', 'off', 'Color', [0.95, 0.95, 0.95]); % 添加标题 uicontrol('Style', 'text', 'String', '请选择分选算法', ... 'Position', [100, 180, 200, 40], ... 'FontSize', 16, 'FontWeight', 'bold', ... 'BackgroundColor', [0.95, 0.95, 0.95]); % SDIF算法按钮 uicontrol('Style', 'pushbutton', 'String', 'SDIF 算法', ... 'Position', [100, 120, 200, 40], ... 'FontSize', 14, 'FontWeight', 'bold', ... 'BackgroundColor', [0.4, 0.8, 1.0], ... 'Callback', @sdif_callback); % CDIF算法按钮 uicontrol('Style', 'pushbutton', 'String', 'CDIF 算法', ... 'Position', [100, 60, 200, 40], ... 'FontSize', 14, 'FontWeight', 'bold', ... 'BackgroundColor', [1.0, 0.8, 0.4], ... 'Callback', @cdif_callback); % SDIF算法回调函数 function sdif_callback(~, ~) close(mainFig); % 关闭主界面 sdif_gui(); % 打开SDIF参数设置界面 end % CDIF算法回调函数 function cdif_callback(~, ~) close(mainFig); % 关闭主界面 CDIF_GUI(); % 打开CDIF参数设置界面 end end function sdif_gui() % SDIF算法参数设置界面 % 允许用户设置SDIF算法的各项参数 fig = figure('Name', 'SDIF参数设置', 'NumberTitle', 'off', ... 'Position', [300, 200, 500, 500], 'MenuBar', 'none', ... 'Color', [0.95, 0.95, 0.95]); % 默认参数值 defaultParams = struct(... 'filename', 'PDW2.txt', ... % 数据文件名 'bin_size', 5, ... % 直方图箱大小(µs) 'max_interval', 1200, ... % 最大间隔(µs) 'A', 0.4, ... % 门限参数A 'lambda', 0.25, ... % 脉冲流密度λ 'max_order', 8, ... % 最大直方图阶数 'tolerance', 3, ... % 容差范围(µs) 'min_seq_length', 5 ... % 序列最小长度 ); % 界面标题 uicontrol('Style', 'text', 'String', 'SDIF参数配置', ... 'Position', [150, 450, 200, 30], ... 'FontSize', 16, 'FontWeight', 'bold', ... 'BackgroundColor', [0.95, 0.95, 0.95]); % 创建参数输入控件 params = fieldnames(defaultParams); yPos = 400; % 初始Y坐标 controls = struct(); % 存储控件句柄 for i = 1:length(params) param = params{i}; value = defaultParams.(param); % 参数标签 uicontrol('Style', 'text', 'String', [strrep(param, '_', ' '), ':'], ... 'Position', [50, yPos, 150, 25], ... 'HorizontalAlignment', 'left', ... 'FontSize', 12, ... 'BackgroundColor', [0.95, 0.95, 0.95]); % 参数输入框 if isnumeric(value) valueStr = num2str(value); else valueStr = value; end ctrl = uicontrol('Style', 'edit', ... 'String', valueStr, ... 'Position', [220, yPos, 150, 25], ... 'FontSize', 11, ... 'Tag', param); controls.(param) = ctrl; yPos = yPos - 40; % 下移位置 end % 文件浏览按钮 uicontrol('Style', 'pushbutton', 'String', '浏览...', ... 'Position', [380, 400, 80, 25], ... 'FontSize', 10, ... 'Callback', @browseFile); % 运行分析按钮 uicontrol('Style', 'pushbutton', 'String', '运行 SDIF 分析', ... 'Position', [150, 50, 200, 40], ... 'FontSize', 14, 'FontWeight', 'bold', ... 'BackgroundColor', [0.4, 0.8, 0.4], ... 'Callback', @runAnalysis); % 返回主菜单按钮 uicontrol('Style', 'pushbutton', 'String', '返回主菜单', ... 'Position', [20, 20, 100, 30], ... 'Callback', @returnToMain); % 文件浏览回调函数 function browseFile(~, ~) [file, path] = uigetfile('*.txt', '选择数据文件'); if file set(controls.filename, 'String', fullfile(path, file)); end end % 运行分析回调函数 function runAnalysis(~, ~) % 获取用户输入的参数值 params = struct(); paramNames = fieldnames(defaultParams); for i = 1:length(paramNames) name = paramNames{i}; strVal = get(controls.(name), 'String'); if strcmp(name, 'filename') params.(name) = strVal; % 文件名直接使用字符串 else params.(name) = str2double(strVal); % 其他参数转换为数值 end end % 验证文件是否存在 if ~isfile(params.filename) errordlg('数据文件不存在!', '文件错误'); return; end try % 运行SDIF算法 [sequences, pris, remaining_toa] = run_sdif(... params.filename, ... params.bin_size, ... params.max_interval, ... params.A, ... params.lambda, ... params.max_order, ... params.tolerance, ... params.min_seq_length); % 显示结果 show_sdif_results(sequences, pris, remaining_toa); catch ME % 错误处理 errordlg(sprintf('分析错误: %s', ME.message), '分析错误'); end end % 返回主菜单回调函数 function returnToMain(~, ~) close(fig); % 关闭当前界面 radar_signal_sorting_gui(); % 重新打开主界面 end end function [sequences, pris, remaining_toa] = run_sdif(filename, bin_size, max_interval, A, lambda, max_order, tolerance, min_seq_length) % SDIF算法核心执行函数 % 读取数据文件并执行SDIF分选算法 % 读取数据文件 fid = fopen(filename, 'r'); data = textscan(fid, '%f %f %f %f %f'); fclose(fid); data = [data{1}, data{2}, data{3}, data{4}, data{5}]; % 提取到达时间(TOA)并排序 toa = data(:, 4); [toa_sorted, sort_idx] = sort(toa); data_sorted = data(sort_idx, :); % 计算直方图箱数 num_bins = floor(max_interval / bin_size); % 执行SDIF核心算法 [sequences, pris, remaining_toa] = sdif_core(... toa_sorted, bin_size, max_interval, num_bins, ... A, lambda, max_order, tolerance, min_seq_length); end function show_sdif_results(sequences, pris, remaining_toa) % 显示SDIF分选结果 % 创建结果展示界面,包含表格和多种图表 fig = figure('Name', 'SDIF分选结果', 'NumberTitle', 'off', ... 'Position', [300, 50, 1200, 800], 'MenuBar', 'none'); % 结果摘要面板 summaryPanel = uipanel('Title', '分选结果摘要', 'Position', [0.02, 0.85, 0.96, 0.13], ... 'FontSize', 12, 'FontWeight', 'bold'); % 计算统计信息 totalPulses = sum(cellfun(@length, sequences)) + length(remaining_toa); extracted = length(pris(pris>0)); % 提取的有效序列数 % 显示摘要信息 uicontrol('Parent', summaryPanel, 'Style', 'text', ... 'String', sprintf('提取序列数: %d | 总脉冲数: %d | 剩余脉冲: %d', ... extracted, totalPulses, length(remaining_toa)), ... 'Position', [20, 40, 900, 30], ... 'FontSize', 14, 'FontWeight', 'bold', ... 'HorizontalAlignment', 'left'); % 结果表格 resultTable = uitable(fig, 'Position', [50, 450, 1100, 150], ... 'ColumnName', {'序列ID', 'PRI(μs)', '脉冲数', '起始时间(μs)', '结束时间(μs)'}, ... 'ColumnWidth', {120, 210, 210, 240, 240}, ... 'FontSize', 12); % 填充表格数据 tableData = cell(length(sequences), 5); for i = 1:length(sequences) seq = sequences{i}; % 处理未知PRI值 pri_val = ifelse(pris(i)>0, sprintf('%.1f', pris(i)), '未知'); tableData{i,1} = i; tableData{i,2} = pri_val; tableData{i,3} = length(seq); tableData{i,4} = min(seq); tableData{i,5} = max(seq); end set(resultTable, 'Data', tableData); % 创建选项卡组 tabGroup = uitabgroup(fig, 'Position', [0.05, 0.05, 0.9, 0.5]); % 选项卡1: 序列脉冲分布 tab1 = uitab(tabGroup, 'Title', '序列脉冲分布'); ax1 = axes('Parent', tab1); hold(ax1, 'on'); grid(ax1, 'on'); % 为每个序列分配不同颜色 colors = lines(length(sequences)); % 绘制每个序列的脉冲分布 for i = 1:length(sequences) seq = sequences{i}; y_pos = i * ones(size(seq)); scatter(ax1, seq, y_pos, 40, colors(i,:), 'filled'); plot(ax1, seq, y_pos, 'Color', colors(i,:), 'LineWidth', 1.5); % 添加序列信息标注 if pris(i) > 0 text(ax1, min(seq), i+0.3, sprintf('序列%d: PRI=%.1fµs', i, pris(i)), ... 'Color', colors(i,:), 'FontSize', 10); end end % 绘制未分选脉冲 if ~isempty(remaining_toa) y_pos = (length(sequences)+1) * ones(size(remaining_toa)); scatter(ax1, remaining_toa, y_pos, 40, [0.8 0.2 0.2], 'filled'); text(ax1, min(remaining_toa), length(sequences)+1.3, '未分选脉冲', ... 'Color', [0.8 0.2 0.2], 'FontSize', 10); end % 设置坐标轴范围 ylim(ax1, [0, length(sequences)+2]); xlabel(ax1, '到达时间(TOA, µs)'); ylabel(ax1, '信号序列'); title(ax1, '脉冲序列分布'); % 选项卡2: 脉冲数量统计 tab2 = uitab(tabGroup, 'Title', '脉冲数量统计'); ax2 = axes('Parent', tab2); % 计算每个序列的脉冲数量 pulseCounts = cellfun(@length, sequences); validSeqs = find(pris > 0); % 只统计有效序列 % 绘制条形图 bar(ax2, validSeqs, pulseCounts(validSeqs), 'FaceColor', [0.3, 0.6, 0.9]); % 添加数量标签 for i = 1:length(validSeqs) text(ax2, validSeqs(i), pulseCounts(validSeqs(i))+0.5, ... num2str(pulseCounts(validSeqs(i))), ... 'HorizontalAlignment', 'center', 'FontSize', 10); end xlabel(ax2, '序列ID'); ylabel(ax2, '脉冲数量'); title(ax2, '各序列脉冲数量统计'); grid(ax2, 'on'); set(ax2, 'XTick', validSeqs); % 选项卡3: PRI分布 tab3 = uitab(tabGroup, 'Title', 'PRI分布'); ax3 = axes('Parent', tab3); % 提取有效PRI值 valid_pris = pris(pris > 0); if ~isempty(valid_pris) % 绘制直方图 hist(ax3, valid_pris, 20); xlabel(ax3, 'PRI值(µs)'); ylabel(ax3, '出现次数'); title(ax3, '提取的PRI值分布'); grid(ax3, 'on'); else % 无有效PRI时显示提示 text(ax3, 0.5, 0.5, '未检测到有效PRI', ... 'HorizontalAlignment', 'center', 'FontSize', 14); end % 返回主菜单按钮 uicontrol('Style', 'pushbutton', 'String', '返回主菜单', ... 'Position', [50, 20, 120, 30], ... 'Callback', @returnToMain); % 返回主菜单回调函数 function returnToMain(~, ~) close(fig); % 关闭结果界面 radar_signal_sorting_gui(); % 重新打开主界面 end end % 条件判断辅助函数 function s = ifelse(condition, true_str, false_str) if condition s = true_str; else s = false_str; end end % SDIF核心算法实现 function [sequences, pris, remaining_toa] = sdif_core(... toa_data, bin_size, max_interval, num_bins, ... A, lambda, max_order, tolerance, min_seq_length) % 初始化变量 n_pulses = length(toa_data); pulse_mask = true(n_pulses, 1); % 脉冲掩码,标记哪些脉冲未被分选 sequences = {}; % 存储分选出的序列 pris = []; % 存储每个序列的PRI值 iteration = 0; % 迭代计数器 % 主循环:当剩余脉冲数足够时分选 while nnz(pulse_mask) >= min_seq_length iteration = iteration + 1; current_toa = toa_data(pulse_mask); % 当前未被分选的脉冲 n_current = length(current_toa); found_sequence = false; % 标记是否找到序列 % 遍历不同阶数 for order = 1:max_order % 检查脉冲数量是否足够 if n_current < order + 1 continue; end % 计算间隔差 if order == 1 % 一阶:连续脉冲间的间隔 intervals = current_toa(2:end) - current_toa(1:end-1); else % 高阶:间隔order个脉冲的间隔差 intervals = current_toa(order+1:end) - current_toa(1:end-order); end % 计算直方图 [hist_counts, bin_edges] = histcounts(intervals, num_bins, 'BinLimits', [0, max_interval]); bin_centers = bin_edges(1:end-1) + bin_size/2; % 计算SDIF门限 E = n_current; % 当前脉冲数量 C = order; % 当前阶数 threshold_values = A * (E - C) * exp(-lambda * bin_centers); % 找出超过门限的箱 exceed_idx = find(hist_counts > threshold_values); if ~isempty(exceed_idx) % 选择PRI候选值 if order == 1 if numel(exceed_idx) == 1 pri_candidate = bin_centers(exceed_idx(1)); else % 多个候选时选择最小PRI(子谐波检验) [min_pri, min_idx] = min(bin_centers(exceed_idx)); pri_candidate = min_pri; end else % 高阶选择最小PRI [min_pri, min_idx] = min(bin_centers(exceed_idx)); pri_candidate = min_pri; end % 搜索序列 [seq_found, seq_idx] = find_sequence_sdif(... current_toa, pri_candidate, tolerance, min_seq_length); if seq_found % 转换为全局索引 global_idx = find(pulse_mask); global_seq_idx = global_idx(seq_idx); % 保存序列 sequences{end+1} = current_toa(seq_idx); pris(end+1) = pri_candidate; % 更新脉冲掩码 pulse_mask(global_seq_idx) = false; found_sequence = true; break; % 找到序列后跳出阶数循环 end end end % 未找到新序列时终止分选 if ~found_sequence break; end end % 处理剩余脉冲 remaining_toa = toa_data(pulse_mask); if ~isempty(remaining_toa) sequences{end+1} = remaining_toa; pris(end+1) = 0; % 未知PRI end end % 查找序列函数 function [found, seq_indices] = find_sequence_sdif(toa, pri, tolerance, min_length) % 使用动态规划算法查找最长的连续序列 n = length(toa); dp = ones(1, n); % dp[i]表示以第i个脉冲结尾的序列长度 prev = zeros(1, n); % 前驱指针,记录序列中的前一个脉冲 max_len = 1; % 最长序列长度 max_idx = 1; % 最长序列的结束位置 % 动态规划填表 for i = 2:n dp(i) = 1; prev(i) = 0; % 检查所有可能的j for j = 1:i-1 interval = toa(i) - toa(j); % 检查间隔是否在容差范围内 if abs(interval - pri) <= tolerance % 更新序列长度 if dp(j) + 1 > dp(i) dp(i) = dp(j) + 1; prev(i) = j; end end end % 更新最长序列信息 if dp(i) > max_len max_len = dp(i); max_idx = i; end end % 检查序列是否满足最小长度要求 if max_len >= min_length found = true; seq_indices = []; current = max_idx; % 回溯重建序列 while current > 0 seq_indices = [current, seq_indices]; current = prev(current); end else found = false; seq_indices = []; end end function CDIF_GUI() % CDIF算法主界面 % 提供参数设置和结果展示功能 fig = figure('Name', 'CDIF脉冲序列分析', 'NumberTitle', 'off', ... 'Position', [200, 100, 1000, 700], 'MenuBar', 'none', ... 'Resize', 'on'); % 参数控制面板 controlPanel = uipanel(fig, 'Title', '参数控制', ... 'Position', [0.02, 0.02, 0.96, 0.96], ... 'FontSize', 14, 'FontWeight', 'bold'); % 默认参数值 defaultParams = struct(... 'filename', 'PDW1.txt', ... % 数据文件名 'max_level', 2, ... % 最大分析层级 'a', 0.4, ... % 门限参数a 'tolerance', 0.01, ... % 容差 'min_pulse_sequence', 5, ... % 最小脉冲序列长度 'min_total_pulses', 0 ... % 最小总脉冲数 ); % 文件选择控件 uicontrol(controlPanel, 'Style', 'text', 'String', '数据文件:', ... 'Units', 'normalized', 'Position', [0.05, 0.85, 0.15, 0.05], ... 'HorizontalAlignment', 'left', 'FontSize', 12); fileEdit = uicontrol(controlPanel, 'Style', 'edit', ... 'String', defaultParams.filename, ... 'Units', 'normalized', 'Position', [0.20, 0.85, 0.45, 0.05], ... 'FontSize', 12); uicontrol(controlPanel, 'Style', 'pushbutton', 'String', '浏览...', ... 'Units', 'normalized', 'Position', [0.70, 0.85, 0.15, 0.05], ... 'FontSize', 12, ... 'Callback', @(src,evt) browseFile(fileEdit)); % 参数输入控件 params = fieldnames(defaultParams); paramControls = struct(); paramControls.filename = fileEdit; paramYPos = 0.75; % 初始Y坐标 paramSpacing = 0.08; % 控件间距 % 创建参数控件 for i = 2:length(params) paramName = params{i}; paramValue = defaultParams.(paramName); % 参数标签 uicontrol(controlPanel, 'Style', 'text', ... 'String', [replace(paramName, '_', ' '), ':'], ... 'Units', 'normalized', 'Position', [0.05, paramYPos, 0.25, 0.05], ... 'HorizontalAlignment', 'left', 'FontSize', 12); % 整数参数使用编辑框 if ismember(paramName, {'max_level', 'min_pulse_sequence', 'min_total_pulses'}) paramControls.(paramName) = uicontrol(controlPanel, 'Style', 'edit', ... 'String', num2str(paramValue), ... 'Units', 'normalized', 'Position', [0.35, paramYPos, 0.15, 0.05], ... 'Tag', paramName, 'FontSize', 12); else % 浮点参数使用编辑框+滑块 paramControls.(paramName) = uicontrol(controlPanel, 'Style', 'edit', ... 'String', num2str(paramValue), ... 'Units', 'normalized', 'Position', [0.35, paramYPos, 0.15, 0.05], ... 'Tag', paramName, 'FontSize', 12); % 添加滑块 uicontrol(controlPanel, 'Style', 'slider', ... 'Min', 0, 'Max', 1, ... 'Value', paramValue, ... 'Units', 'normalized', 'Position', [0.55, paramYPos, 0.30, 0.05], ... 'Tag', [paramName, 'Slider'], ... 'Callback', @(src,evt) sliderCallback(src, paramName, paramControls.(paramName))); end paramYPos = paramYPos - paramSpacing; % 下移位置 end % 运行分析按钮 uicontrol(controlPanel, 'Style', 'pushbutton', 'String', '运行分析', ... 'Units', 'normalized', 'Position', [0.35, 0.05, 0.30, 0.08], ... 'FontWeight', 'bold', 'FontSize', 14, ... 'Callback', @(src,evt) runAnalysis(fig, paramControls)); % 文件浏览回调函数 function browseFile(editControl) [file, path] = uigetfile('*.txt', '选择数据文件'); if file set(editControl, 'String', fullfile(path, file)); end end % 滑块回调函数 function sliderCallback(src, paramName, editControl) value = get(src, 'Value'); set(editControl, 'String', num2str(value)); end % 运行分析回调函数 function runAnalysis(fig, paramControls) % 获取参数值 filename = get(paramControls.filename, 'String'); max_level = str2double(get(paramControls.max_level, 'String')); a = str2double(get(paramControls.a, 'String')); tolerance = str2double(get(paramControls.tolerance, 'String')); min_pulse_sequence = str2double(get(paramControls.min_pulse_sequence, 'String')); min_total_pulses = str2double(get(paramControls.min_total_pulses, 'String')); % 验证参数有效性 if isnan(max_level) || max_level < 1 || max_level > 10 errordlg('最大层级必须为1-10之间的整数', '参数错误'); return; end if isnan(a) || a < 0 || a > 1 errordlg('门限参数a必须在0-1范围内', '参数错误'); return; end % 删除现有结果面板(如果存在) if ishandle(findobj(fig, 'Tag', 'resultPanel')) delete(findobj(fig, 'Tag', 'resultPanel')); end try % 运行CDIF分析 [all_sequences, all_pri, remaining_toa, all_seq_cdif_data] = ... optimized_CDIF(filename, max_level, a, tolerance, min_pulse_sequence, min_total_pulses); % 创建结果面板 resultPanel = uipanel(fig, 'Title', '分析结果', ... 'Position', [0.02, 0.02, 0.96, 0.96], ... 'Units', 'normalized', ... 'Tag', 'resultPanel', ... 'FontSize', 14, 'FontWeight', 'bold'); % 添加返回按钮 uicontrol(resultPanel, 'Style', 'pushbutton', 'String', '返回控制面板', ... 'Units', 'normalized', 'Position', [0.01, 0.01, 0.15, 0.04], ... 'FontSize', 12, ... 'Callback', @(src,evt) delete(resultPanel)); % 创建结果表格 resultTable = uitable(resultPanel, 'Units', 'normalized', ... 'Position', [0.02, 0.75, 0.96, 0.23], ... 'ColumnName', {'序列ID', 'PRI (μs)', '脉冲数量', '分析层级'}, ... 'ColumnFormat', {'numeric', 'numeric', 'numeric', 'numeric'}, ... 'ColumnWidth', {220, 220, 250, 200}, ... 'Tag', 'resultTable', ... 'FontSize', 12); % 显示结果摘要 summaryStr = sprintf('提取序列总数: %d | 剩余脉冲数: %d', ... length(all_sequences), length(remaining_toa)); uicontrol(resultPanel, 'Style', 'text', ... 'Units', 'normalized', ... 'Position', [0.02, 0.70, 0.96, 0.05], ... 'String', summaryStr, ... 'FontSize', 14, 'FontWeight', 'bold', ... 'HorizontalAlignment', 'left'); % 更新结果表格数据 if ~isempty(all_sequences) resultData = cell(length(all_sequences), 4); for i = 1:length(all_sequences) resultData{i,1} = i; % 序列ID resultData{i,2} = all_pri(i); % PRI resultData{i,3} = length(all_sequences{i}); % 脉冲数量 % 查找分析层级 level_found = 0; for lvl = 1:length(all_seq_cdif_data) if lvl <= length(all_seq_cdif_data) && ... ~isempty(all_seq_cdif_data{lvl}) && ... any([all_seq_cdif_data{lvl}.seq_id] == i) resultData{i,4} = lvl; level_found = 1; break; end end if ~level_found resultData{i,4} = '未知'; end end else resultData = {}; end set(resultTable, 'Data', resultData); % 创建图形面板 - 使用选项卡 tabGroup = uitabgroup(resultPanel, 'Units', 'normalized', ... 'Position', [0.02, 0.05, 0.96, 0.65]); % CDIF分析结果选项卡 cdifTab = uitab(tabGroup, 'Title', 'CDIF分析结果'); % 序列脉冲统计选项卡 pulseTab = uitab(tabGroup, 'Title', '序列脉冲统计'); % 创建CDIF分析结果图 if ~isempty(all_seq_cdif_data) % 计算实际有数据的层级 valid_levels = sum(~cellfun(@isempty, all_seq_cdif_data)); if valid_levels > 0 % 计算网格布局(每行最多2列) grid_cols = min(2, valid_levels); grid_rows = ceil(valid_levels / grid_cols); level_counter = 1; for lvl = 1:length(all_seq_cdif_data) if ~isempty(all_seq_cdif_data{lvl}) % 创建坐标轴 ax = subplot(grid_rows, grid_cols, level_counter, 'Parent', cdifTab); set(ax, 'Tag', ['axes', num2str(lvl)], 'FontSize', 12); % 绘制该层级的CDIF结果 plot_combined_cdif_gui(all_seq_cdif_data{lvl}, lvl, ax); level_counter = level_counter + 1; end end end else % 无CDIF数据时显示提示 uicontrol(cdifTab, 'Style', 'text', 'String', '未找到CDIF分析数据', ... 'Units', 'normalized', 'Position', [0.3, 0.5, 0.4, 0.1], ... 'FontSize', 14, 'FontWeight', 'bold'); end % 创建序列脉冲统计图 if ~isempty(all_sequences) axHist = axes('Parent', pulseTab, 'FontSize', 12); % 获取序列ID和脉冲数量 seqIds = 1:length(all_sequences); pulseCounts = cellfun(@length, all_sequences); % 绘制条形图 bar(axHist, seqIds, pulseCounts, 'FaceColor', [0.3, 0.6, 0.9]); % 添加数值标签 for i = 1:length(seqIds) text(axHist, seqIds(i), pulseCounts(i)+0.1, num2str(pulseCounts(i)), ... 'HorizontalAlignment', 'center', 'FontSize', 12); end title(axHist, '序列脉冲数量统计', 'FontSize', 14); xlabel(axHist, '序列ID', 'FontSize', 12); ylabel(axHist, '脉冲数量', 'FontSize', 12); grid(axHist, 'on'); set(axHist, 'XTick', seqIds); else % 无有效序列时显示提示 uicontrol(pulseTab, 'Style', 'text', 'String', '未找到有效序列', ... 'Units', 'normalized', 'Position', [0.3, 0.5, 0.4, 0.1], ... 'FontSize', 14, 'FontWeight', 'bold'); end catch ME % 错误处理 errordlg(sprintf('分析错误: %s', ME.message), '分析错误'); end end % CDIF结果绘图函数 function plot_combined_cdif_gui(cdif_data, level, ax) axes(ax); % 设置当前坐标轴 cla(ax); % 清除原有内容 % 获取最大PRI范围和最大直方图值 max_pri_len = max(arrayfun(@(x) length(x.hist), cdif_data)); max_hist_val = max(arrayfun(@(x) max(x.hist), cdif_data)); % 创建颜色映射 colors = lines(length(cdif_data)); hold(ax, 'on'); % 绘制所有序列的直方图 for i = 1:length(cdif_data) data = cdif_data(i); x = 1:length(data.hist); % 绘制直方图 plot(ax, x, data.hist, 'Color', colors(i, :), 'LineWidth', 1.5, ... 'DisplayName', sprintf('序列%d (PRI=%.1fµs)', data.seq_id, data.pri)); % 找到最接近实际PRI的索引位置 [~, idx] = min(abs(x - data.pri)); peak_value = data.hist(idx); % 标记检测到的PRI plot(ax, x(idx), peak_value, 'o', 'MarkerSize', 8, ... 'MarkerFaceColor', colors(i, :), 'MarkerEdgeColor', 'k', ... 'HandleVisibility', 'off'); end % 绘制统一的门限曲线 if ~isempty(cdif_data) x_thresh = 1:length(cdif_data(1).threshold); plot(ax, x_thresh, cdif_data(1).threshold, 'k--', 'LineWidth', 1.5, ... 'DisplayName', '最优门限'); end hold(ax, 'off'); % 添加图例和标签 title(ax, sprintf('层级 %d CDIF分析', level), 'FontSize', 14); xlabel(ax, 'PRI (\mu s)', 'FontSize', 12); ylabel(ax, '累积计数', 'FontSize', 12); legend(ax, 'show', 'Location', 'best', 'FontSize', 10); grid(ax, 'on'); % 设置坐标轴范围 xlim(ax, [1, min(max_pri_len, 100000)]); % 限制X轴范围 % 动态设置Y轴范围 if max_hist_val > 0 ylim(ax, [0, max_hist_val * 1.2]); % 基于数据设置Y轴 else ylim(ax, [0, 10]); % 默认范围 end % 设置坐标轴字体大小 set(ax, 'FontSize', 12); end end function [all_sequences, all_pri, remaining_toa, all_seq_cdif_data] = optimized_CDIF(filename, max_level, a, tolerance, min_pulse_sequence, min_total_pulses) % CDIF算法核心实现 % 读取数据并执行CDIF分选算法 % 读取数据 data = load(filename); toa_original = data(:,4); toa_original = sort(toa_original); % 排序到达时间 remaining_toa = toa_original; % 剩余脉冲 % 计算总时间范围和最大PRI T_total = max(toa_original) - min(toa_original); absolute_max_pri = 1000000; % 1000ms PRI_max = min(T_total/2, absolute_max_pri); % 存储结果 all_sequences = {}; % 所有分选出的序列 all_pri = []; % 各序列的PRI值 sequence_counter = 1; % 序列计数器 all_seq_cdif_data = cell(1, max_level); % 各层级的CDIF数据 % 主循环:处理所有序列 while length(remaining_toa) >= min_total_pulses % 提取下一个序列 [sequence, pri, level, remaining_toa, level_hists] = extract_next_sequence(... remaining_toa, PRI_max, a, tolerance, ... min_pulse_sequence, max_level); if ~isempty(sequence) % 保存序列信息 all_sequences{end+1} = sequence; all_pri(end+1) = pri; % 保存CDIF数据 for lvl = 1:length(level_hists) level_data = level_hists{lvl}; if lvl <= max_level if isempty(all_seq_cdif_data{lvl}) all_seq_cdif_data{lvl} = struct(... 'seq_id', sequence_counter, ... 'hist', level_data.hist, ... 'threshold', level_data.threshold, ... 'pri', pri); else all_seq_cdif_data{lvl}(end+1) = struct(... 'seq_id', sequence_counter, ... 'hist', level_data.hist, ... 'threshold', level_data.threshold, ... 'pri', pri); end end end sequence_counter = sequence_counter + 1; else break; % 未找到新序列时退出 end end end % 提取下一个序列 function [sequence, pri, level, remaining_toa, level_hists] = extract_next_sequence(... toa, PRI_max, a, tolerance, min_pulse_sequence, max_level) level_hists = {}; % 存储各层级直方图 cumulative_hist = []; % 累积直方图 T_total = max(toa) - min(toa); % 当前脉冲流的总时间 % CDIF分析循环 (从1级到max_level) for current_level = 1:max_level % 计算当前级别的直方图 [level_hist, thresholds] = compute_level_hist(toa, current_level, PRI_max, T_total, a); % 累积到前一级的直方图 if isempty(cumulative_hist) cumulative_hist = level_hist; else % 确保直方图长度一致 max_len = max(length(cumulative_hist), length(level_hist)); cumulative_hist(end+1:max_len) = 0; level_hist(end+1:max_len) = 0; cumulative_hist = cumulative_hist + level_hist; end % 保存当前层级数据 level_data.hist = cumulative_hist; level_data.threshold = thresholds; level_hists{end+1} = level_data; % 寻找候选PRI(高于门限) candidate_indices = find(cumulative_hist > thresholds); % 过滤无效PRI候选值 candidate_indices(candidate_indices < 10) = []; % 过滤过小的PRI candidate_indices(candidate_indices > PRI_max) = []; % 过滤过大的PRI if ~isempty(candidate_indices) % 按显著性排序(直方图值降序) [sorted_values, sort_idx] = sort(cumulative_hist(candidate_indices), 'descend'); candidate_pri = candidate_indices(sort_idx); % 尝试提取序列 for i = 1:length(candidate_pri) tolerance_val = candidate_pri(i) * tolerance; [sequence, new_toa] = extract_sequence(toa, candidate_pri(i), tolerance_val, min_pulse_sequence); if ~isempty(sequence) pri = candidate_pri(i); level = current_level; remaining_toa = new_toa; return; % 成功提取序列后返回 end end end end % 未找到序列 pri = []; level = []; sequence = []; remaining_toa = toa; level_hists = {}; end % 计算层级直方图 function [level_hist, thresholds] = compute_level_hist(toa, level, PRI_max, T_total, a) % 初始化直方图 level_hist = zeros(1, ceil(PRI_max)); % 检查是否有足够脉冲计算当前层级 if length(toa) > level % 计算当前级别的dTOA(到达时间差) dtoa = toa(level+1:end) - toa(1:end-level); % 过滤有效值(在1和PRI_max之间) valid_indices = (dtoa >= 1) & (dtoa <= PRI_max); dtoa = dtoa(valid_indices); % 统计直方图 for i = 1:length(dtoa) idx = min(ceil(dtoa(i)), length(level_hist)); % 计算索引 if idx > 0 level_hist(idx) = level_hist(idx) + 1; % 增加计数 end end end % 计算最优门限函数 D_{cdif} = a * T / t t = 1:length(level_hist); thresholds = a * T_total ./ t; % 处理除零和无效值 thresholds(isinf(thresholds) | isnan(thresholds)) = max(level_hist); thresholds(t == 0) = max(level_hist); % 确保门限不低于最小值 min_threshold = 3; % 最小门限值 thresholds(thresholds < min_threshold) = min_threshold; end % 提取序列函数 function [sequence, remaining] = extract_sequence(toa, pri, tolerance_val, min_length) sequence = []; remaining = toa; % 检查是否有足够脉冲 if length(toa) < min_length return; end best_sequence = []; % 最佳序列 best_length = 0; % 最佳序列长度 % 尝试不同的起点(最多尝试20个起点) for start_idx = 1:min(20, length(toa)) current_sequence = toa(start_idx); % 当前序列 current_time = toa(start_idx); % 当前时间 last_index = start_idx; % 最后索引 lost_count = 0; % 丢失脉冲计数 total_missed = 0; % 总丢失脉冲数 % 向前搜索 for j = (start_idx+1):length(toa) expected_time = current_time + pri; % 期望到达时间 % 检查当前脉冲是否在期望时间附近 if abs(toa(j) - expected_time) <= tolerance_val % 添加脉冲到序列 current_sequence(end+1) = toa(j); current_time = toa(j); last_index = j; lost_count = 0; % 重置丢失计数 % 检查是否可能丢失脉冲 elseif toa(j) > expected_time + tolerance_val % 计算可能丢失的脉冲数 missed_count = floor((toa(j) - expected_time) / pri); % 检查是否在容差范围内 next_expected = expected_time + missed_count * pri; if abs(toa(j) - next_expected) <= tolerance_val % 添加脉冲到序列 current_sequence(end+1) = toa(j); current_time = toa(j); last_index = j; lost_count = lost_count + missed_count; total_missed = total_missed + missed_count; else % 如果脉冲差距太大,可能不是同一个序列 if lost_count >= 2 break; end end end end % 检查序列质量 if length(current_sequence) >= min_length % 计算序列持续时间 duration = current_sequence(end) - current_sequence(1); % 序列质量标准: % 1. 序列持续时间至少为2倍PRI % 2. 丢失脉冲比例不超过50% if duration >= 2 * pri && (total_missed / length(current_sequence)) <= 0.5 if length(current_sequence) > best_length best_sequence = current_sequence; best_length = length(current_sequence); end end end end % 验证序列长度 if best_length >= min_length sequence = best_sequence; % 从原始TOA中移除序列 [~, idx] = ismember(sequence, toa); remaining = toa; remaining(idx) = []; end end 分析上述代码的设计思路
06-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值