【测速】矩阵翻转

[size=large]在微博中看到有人分享了篇文章“为什么转置512×512矩阵,会比513×513矩阵慢很多?”[/size][url]http://note.sdo.com/u/1557869253/n/sSPb5~k5HYUMLX0mU000QX[/url]
[size=large]没仔细看原理,但与缓存的命中率有关。
今天写矩阵翻转的代码,突然想到这个问题。测了一下速度:[/size]
[color=red][size=xx-large]结论:[/size][/color][size=large]新建一片内存,顺序访问其中的元素,速度比较快!!!在翻转中能快个两倍左右!!!(注:我的矩阵是行优先存储的)[/size]


[color=red][size=xx-large]有关代码如下(代码不完全):[/size][/color]
	//水平翻转矩阵中的元素
void flipHorizontally(){
T tmp;
//int halfHeight=height_row/2;
int halfWidth=width_col/2;
for (int r=0; r<height_row; r++) {
for (int c=0; c<halfWidth; c++) {
int c2=width_col-1-c;
tmp=getValue(r,c);
this->operator()(r,c)=this->operator()(r,c2);
this->operator()(r,c2)=tmp;
}
}

}

//水平翻转矩阵中的元素
Matrix flipHorizontallyNewMatrix(){
Matrix flipped(height_row,width_col);
int halfWidth=width_col/2;
for (int r=0; r<height_row; r++) {
for (int c=0; c<=halfWidth; c++) {
int c2=width_col-1-c;
flipped(r,c)=this->operator()(r,c2);
flipped(r,c2)=this->operator()(r,c);
}
}
return flipped;
}

//水平翻转矩阵中的元素
Matrix flipHorizontallyNewMatrix2(){
Matrix flipped(height_row,width_col);
for (int r=0; r<height_row; r++) {
for (int c=0; c<width_col; c++) {
int c2=width_col-1-c;
flipped(r,c)=this->operator()(r,c2);
}
}
return flipped;
}


//垂直翻转矩阵中的元素
Matrix flipVerticallyNewMatrix(){
Matrix flipped(height_row,width_col);
int halfHeight=height_row/2;
for (int r=0; r<=halfHeight; r++) {
for (int c=0; c<width_col; c++) {
int r2=height_row-1-r;
flipped(r,c)=this->operator()(r2,c);
flipped(r2,c)=this->operator()(r,c);
}
}
return flipped;
}

//垂直翻转矩阵中的元素
Matrix flipVerticallyNewMatrix2(){
Matrix flipped(height_row,width_col);
for (int r=0; r<height_row; r++) {
for (int c=0; c<width_col; c++) {
int r2=height_row-1-r;
flipped(r,c)=this->operator()(r2,c);
//flipped(r2,c)=this->operator()(r,c);
}
}
return flipped;
}


//垂直翻转矩阵中的元素
void flipVertically(){
T tmp;
int halfHeight=height_row/2;
for (int r=0; r<halfHeight; r++) {
for (int c=0; c<width_col; c++) {
int r2=height_row-1-r;
tmp=getValue(r,c);
this->operator()(r,c)=this->operator()(r2,c);
this->operator()(r2,c)=tmp;
}
}

}



[color=red][size=xx-large]测试用的代码如下(代码不完全):[/size][/color]

for (int n=10; n<1000; n+=33) {


MatrixInt m(n,n);
for (int i=0; i<m.getNumEl(); i++) {
m(i)=i;
}

int testNum=10000/n*10000/n;
Timer timer;

for(int i=0; i<testNum; i++)
m.flipVerticallyNewMatrix();
long tv1=timer.getElapsedTimeAndRestart();

for(int i=0; i<testNum; i++)
m.flipVerticallyNewMatrix2();
long tv2=timer.getElapsedTimeAndRestart();

for(int i=0; i<testNum; i++)
m.flipVertically();
long tvInplace=timer.getElapsedTimeAndRestart();

for(int i=0; i<testNum; i++)
m.flipHorizontallyNewMatrix();
long th1=timer.getElapsedTimeAndRestart();

for(int i=0; i<testNum; i++)
m.flipHorizontallyNewMatrix2();
long th2=timer.getElapsedTimeAndRestart();

for(int i=0; i<testNum; i++)
m.flipHorizontally();
long thInplace=timer.getElapsedTimeAndRestart();
cout<<"矩阵大小: "<<m.height_row<<"行*"<<m.width_col<<"列"<<endl;
cout<<"水平翻转耗时:方法1: "<<th1<<";\t\t方法2: "<<th2<<";\t\t原位翻转: "<<thInplace<<endl;
cout<<"垂直翻转耗时:方法1: "<<tv1<<";\t\t方法2: "<<tv2<<";\t\t原位翻转: "<<tvInplace<<endl;
cout<<endl;

}



[color=red][size=xx-large]测试用结果如下:[/size][/color]
矩阵大小: 10行*10列
水平翻转耗时:方法1: 566; 方法2: 340; 原位翻转: 410
垂直翻转耗时:方法1: 652; 方法2: 342; 原位翻转: 450

矩阵大小: 43行*43列
水平翻转耗时:方法1: 364; 方法2: 180; 原位翻转: 390
垂直翻转耗时:方法1: 425; 方法2: 178; 原位翻转: 434

矩阵大小: 76行*76列
水平翻转耗时:方法1: 361; 方法2: 188; 原位翻转: 402
垂直翻转耗时:方法1: 433; 方法2: 183; 原位翻转: 445

矩阵大小: 109行*109列
水平翻转耗时:方法1: 360; 方法2: 180; 原位翻转: 397
垂直翻转耗时:方法1: 411; 方法2: 174; 原位翻转: 440

矩阵大小: 142行*142列
水平翻转耗时:方法1: 357; 方法2: 176; 原位翻转: 406
垂直翻转耗时:方法1: 413; 方法2: 173; 原位翻转: 456

矩阵大小: 175行*175列
水平翻转耗时:方法1: 353; 方法2: 173; 原位翻转: 403
垂直翻转耗时:方法1: 412; 方法2: 171; 原位翻转: 452

矩阵大小: 208行*208列
水平翻转耗时:方法1: 359; 方法2: 176; 原位翻转: 408
垂直翻转耗时:方法1: 417; 方法2: 173; 原位翻转: 455

矩阵大小: 241行*241列
水平翻转耗时:方法1: 349; 方法2: 171; 原位翻转: 400
垂直翻转耗时:方法1: 411; 方法2: 170; 原位翻转: 449

矩阵大小: 274行*274列
水平翻转耗时:方法1: 346; 方法2: 173; 原位翻转: 400
垂直翻转耗时:方法1: 406; 方法2: 167; 原位翻转: 448

矩阵大小: 307行*307列
水平翻转耗时:方法1: 343; 方法2: 170; 原位翻转: 400
垂直翻转耗时:方法1: 402; 方法2: 168; 原位翻转: 443

矩阵大小: 340行*340列
水平翻转耗时:方法1: 360; 方法2: 174; 原位翻转: 420
垂直翻转耗时:方法1: 410; 方法2: 169; 原位翻转: 447

矩阵大小: 373行*373列
水平翻转耗时:方法1: 460; 方法2: 259; 原位翻转: 398
垂直翻转耗时:方法1: 512; 方法2: 261; 原位翻转: 443

矩阵大小: 406行*406列
水平翻转耗时:方法1: 456; 方法2: 262; 原位翻转: 403
垂直翻转耗时:方法1: 516; 方法2: 255; 原位翻转: 452

矩阵大小: 439行*439列
水平翻转耗时:方法1: 450; 方法2: 248; 原位翻转: 401
垂直翻转耗时:方法1: 500; 方法2: 249; 原位翻转: 445

矩阵大小: 472行*472列
水平翻转耗时:方法1: 453; 方法2: 269; 原位翻转: 402
垂直翻转耗时:方法1: 513; 方法2: 265; 原位翻转: 450

矩阵大小: 505行*505列
水平翻转耗时:方法1: 433; 方法2: 252; 原位翻转: 390
垂直翻转耗时:方法1: 489; 方法2: 249; 原位翻转: 436

矩阵大小: 538行*538列
水平翻转耗时:方法1: 440; 方法2: 247; 原位翻转: 398
垂直翻转耗时:方法1: 497; 方法2: 247; 原位翻转: 444

矩阵大小: 571行*571列
水平翻转耗时:方法1: 443; 方法2: 256; 原位翻转: 397
垂直翻转耗时:方法1: 496; 方法2: 248; 原位翻转: 440

矩阵大小: 604行*604列
水平翻转耗时:方法1: 439; 方法2: 252; 原位翻转: 402
垂直翻转耗时:方法1: 494; 方法2: 248; 原位翻转: 438

矩阵大小: 637行*637列
水平翻转耗时:方法1: 436; 方法2: 244; 原位翻转: 397
垂直翻转耗时:方法1: 488; 方法2: 242; 原位翻转: 432

矩阵大小: 670行*670列
水平翻转耗时:方法1: 427; 方法2: 243; 原位翻转: 384
垂直翻转耗时:方法1: 483; 方法2: 238; 原位翻转: 427

矩阵大小: 703行*703列
水平翻转耗时:方法1: 449; 方法2: 257; 原位翻转: 403
垂直翻转耗时:方法1: 527; 方法2: 260; 原位翻转: 459

矩阵大小: 736行*736列
水平翻转耗时:方法1: 432; 方法2: 246; 原位翻转: 395
垂直翻转耗时:方法1: 493; 方法2: 245; 原位翻转: 440

矩阵大小: 769行*769列
水平翻转耗时:方法1: 452; 方法2: 258; 原位翻转: 409
垂直翻转耗时:方法1: 518; 方法2: 256; 原位翻转: 458

矩阵大小: 802行*802列
水平翻转耗时:方法1: 434; 方法2: 248; 原位翻转: 392
垂直翻转耗时:方法1: 492; 方法2: 248; 原位翻转: 433

矩阵大小: 835行*835列
水平翻转耗时:方法1: 415; 方法2: 240; 原位翻转: 372
垂直翻转耗时:方法1: 466; 方法2: 234; 原位翻转: 416

矩阵大小: 868行*868列
水平翻转耗时:方法1: 427; 方法2: 247; 原位翻转: 388
垂直翻转耗时:方法1: 478; 方法2: 239; 原位翻转: 433

矩阵大小: 901行*901列
水平翻转耗时:方法1: 448; 方法2: 262; 原位翻转: 400
垂直翻转耗时:方法1: 499; 方法2: 251; 原位翻转: 449

矩阵大小: 934行*934列
水平翻转耗时:方法1: 422; 方法2: 248; 原位翻转: 380
垂直翻转耗时:方法1: 477; 方法2: 237; 原位翻转: 426

矩阵大小: 967行*967列
水平翻转耗时:方法1: 436; 方法2: 257; 原位翻转: 388
垂直翻转耗时:方法1: 493; 方法2: 248; 原位翻转: 438
%% --- 环境初始化 --- clear; % 清除工作区变量 clc; % 清除命令行窗口 close all; % 关闭所有图形窗口 %% 参数设置(保持不变) fc=10e9; lightspeed=299792458; lambda=lightspeed/fc; pd = 0.9; pfa = 1e-6; trcs = 1.5; %% 创建阵列(保持不变) Array = phased.URA('Size',[38 38],... 'Lattice','Rectangular','ArrayNormal','x'); Array.ElementSpacing = [0.5 0.5]*lambda; rwind = hamming(38); cwind = hamming(38); taper = rwind*cwind.'; Array.Taper = taper.'; arraygain = phased.ArrayGain('SensorArray',Array,'PropagationSpeed',physconst('LightSpeed')); ag = arraygain(fc,[0;0]);% 天线法向增益 Elem = phased.IsotropicAntennaElement; Elem.BackBaffled = true; Elem.FrequencyRange = [9.99e9 10.01e9]; Array.Element = Elem; figure; pattern(Array.Element,fc,'PropagationSpeed',physconst('LightSpeed'),... 'Type','powerdb');% 单个天线基本阵子方向图 figure; pattern(Array,fc,'PropagationSpeed',physconst('LightSpeed'),... 'Type','powerdb');% 阵列天线方向图 %% 获取方向图数据 az = -60:0.01:60; % 方位角范围 el = 0; % 固定俯仰角 P = pattern(Array, fc, az, el, 'Type', 'powerdb', ... 'PropagationSpeed', physconst('LightSpeed')); P = P(:); % 确保为列向量 %% 核心:寻找所有峰值(主瓣+旁瓣) % 1. 找到主瓣峰值 [main_peak_val, main_peak_idx] = max(P); main_peak_az = az(main_peak_idx); % 2. 确定主瓣区域(根据3dB波束宽度) half_power = main_peak_val - 3; left_idx = find(P(1:main_peak_idx) <= half_power, 1, 'last'); right_idx = main_peak_idx + find(P(main_peak_idx:end) <= half_power, 1, 'first') - 1; beamwidth = az(right_idx) - az(left_idx); mainlobe_start_idx2 = max(1, main_peak_idx - round(beamwidth/0.01/2)); mainlobe_end_idx2 = min(length(az), main_peak_idx + round(beamwidth/0.01/2)); % 3. 排除主瓣区域 mainlobe_start_idx = max(1, main_peak_idx - round(3.4*beamwidth/0.01/2)); mainlobe_end_idx = min(length(az), main_peak_idx + round(3.4*beamwidth/0.01/2)); % 4. 标记非主瓣区域 sidelobe_mask = true(size(P)); sidelobe_mask(mainlobe_start_idx:mainlobe_end_idx) = false; % 5. 在非主瓣区域寻找所有旁瓣峰值 sidelobe_data = P(sidelobe_mask); sidelobe_az = az(sidelobe_mask); % 使用findpeaks函数寻找旁瓣峰值 [peak_values, peak_indices] = findpeaks(sidelobe_data, ... 'MinPeakDistance', 50,... % 至少50个点(0.5度)的间隔 'MinPeakHeight', main_peak_val - 60); % 只找高于主瓣-60dB的峰值 % 转换回原始索引 sidelobe_peak_indices = find(sidelobe_mask); sidelobe_peak_indices = sidelobe_peak_indices(peak_indices); sidelobe_peak_az = az(sidelobe_peak_indices); % 6. 确定关键旁瓣参数 if ~isempty(peak_values) % 最高旁瓣(SLL) [max_sll_val, max_sll_idx] = max(peak_values); max_sll_az = sidelobe_peak_az(max_sll_idx); max_sll_db = max_sll_val - main_peak_val; % 相对于主瓣的dB值 % 第一旁瓣(最靠近主瓣的旁瓣) [~, first_sll_idx] = min(abs(sidelobe_peak_az - main_peak_az)); first_sll_val = peak_values(first_sll_idx); first_sll_az = sidelobe_peak_az(first_sll_idx); first_sll_db = first_sll_val - main_peak_val; else warning('未找到有效旁瓣峰值,请调整角度范围或参数'); max_sll_db = -inf; first_sll_db = -inf; end %% 绘图显示阵列方向图结果 figure; plot(az, P, 'b', 'LineWidth', 1.2); hold on; % 标记主瓣峰值 plot(main_peak_az, main_peak_val, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r'); text(main_peak_az+1, main_peak_val, '主瓣峰值', 'Color', 'r'); % 标记主瓣区域 fill([az(mainlobe_start_idx2) az(mainlobe_end_idx2) az(mainlobe_end_idx2) az(mainlobe_start_idx2)], ... [min(P) min(P) max(P) max(P)], 'y', 'FaceAlpha', 0.2); text(az(main_peak_idx), min(P)+5, '主瓣区域', 'HorizontalAlignment', 'center'); % 标记所有旁瓣峰值 if ~isempty(peak_values) plot(sidelobe_peak_az, peak_values, 'go', 'MarkerSize', 6, 'MarkerFaceColor', 'g'); % 标记最高旁瓣 plot(max_sll_az, max_sll_val, 'mo', 'MarkerSize', 8, 'MarkerFaceColor', 'm'); text(max_sll_az+1, max_sll_val, sprintf('最高旁瓣: %.1fdB', max_sll_db), 'Color', 'm'); end grid on; xlabel('方位角(度)'); ylabel('功率(dB)'); title('阵列方向图及旁瓣峰值标记'); xlim([min(az) max(az)]); ylim([main_peak_val-70 main_peak_val+5]); %% 输出阵列参数结果 fprintf('主瓣峰值: %.2f dB\n', main_peak_val); fprintf('波束宽度: %.2f 度\n', beamwidth); fprintf('最高旁瓣电平(SLL): %.2f dBc\n', max_sll_db); % dBc表示相对于载波(主瓣) if ~isempty(peak_values) fprintf('第一旁瓣电平: %.2f dBc\n', first_sll_db); end %% 设计线性调频信号 Waveform = phased.LinearFMWaveform('SampleRate',10e+06,... 'PulseWidth',5e-6,'PRF',5000,'SweepBandwidth',10e6,... 'SweepDirection','Up','SweepInterval','Positive'... ,'Envelope','Rectangular','NumPulses',1,'FrequencyOffset',10e9); Fs = Waveform.SampleRate; prf = Waveform.PRF; NumOfPulses = 6; % 用于多普勒分析的脉冲数 tb_product = Waveform.SweepBandwidth * Waveform.PulseWidth;% 时宽带宽积 delta_R = lightspeed / (2*Waveform.SweepBandwidth);% 距离分辨率 delta_v = (lambda * prf) / (2*NumOfPulses);% 速度分辨率 compression_gain = 10*log10(tb_product); % 脉冲压缩增益(dB) snr_min_raw = albersheim(pd, pfa, NumOfPulses); % 未考虑压缩增益的SNR snr_min_actual = snr_min_raw - compression_gain; % 实际所需SNR % 生成基带信号 x = Waveform(); % 匹配滤波 coeff = getMatchedFilter(Waveform); Compression = phased.MatchedFilter('Coefficients',coeff(:,1), ... 'SpectrumWindow','None'); y = Compression(x); %% 设计发射机和接收机 transmitter=phased.Transmitter('PeakPower',1,... 'Gain',20,'InUseOutputPort',true,... 'CoherentOnTransmit',true); receiver=phased.ReceiverPreamp(... "Gain",20,'NoiseFigure',10.0,... 'SampleRate',Fs,'EnableInputPort',true); % 噪声参数计算 F_dB = 7; % 噪声系数 T0 = 290; % 参考温度 (K) L_dB = 10; % 系统损失 k = 1.38e-23; % 玻尔兹曼常数 max_range = 20e3; % 最大探测距离 P_noise = k * T0 * Waveform.SweepBandwidth * db2pow(F_dB); % 噪声功率 % 峰值功率和最大作用距离计算 peak_power = ((4*pi)^3*k*T0*Waveform.SweepBandwidth*db2pow(F_dB)*max_range^4*... db2pow(snr_min_raw))/(db2pow(2*(ag+transmitter.Gain))*trcs*lambda^2); Rmax=((transmitter.PeakPower * db2pow(ag+transmitter.Gain) * db2pow(ag+receiver.Gain)... * lambda^2 * trcs) ./ (P_noise ... * (4 * pi)^3 * db2pow(snr_min_raw))).^(1/4); transmitter.PeakPower = peak_power/1444; %% 目标和传感器运动设置 initialAz = 60; endAz = -60; scanstep = -4; % 扫描步进角度 scangrid = initialAz+scanstep/2:scanstep:endAz; numscans = length(scangrid); pulsenum = NumOfPulses*numscans; % 目标初始位置和速度 % tgtpos = [[19900*cosd(0); 19900*sind(0); 0],[19900*cosd(2); 19900*sind(2); 0],[19900*cosd(4); 19900*sind(4); 0]]; % tgtvel = [[10; 0; 0],[10; 0; 0],[10; 0; 0]];% 目标真实径向速度 tgtpos = [19900*cosd(13); 19900*sind(13); 0]; tgtvel = [-15; 0; 0]; tgtmotion = phased.Platform('InitialPosition',tgtpos,'Velocity',tgtvel); % tgtrcs = [1.5 1.5 1.5];% 目标RCS tgtrcs = 1.5; target = phased.RadarTarget('MeanRCS',tgtrcs,'OperatingFrequency',fc); % 传感器位置(静止) sensorpos = [0; 0; 0]; sensorvel = [0; 0; 0]; sensormotion = phased.Platform('InitialPosition',sensorpos,'Velocity',sensorvel); % 初始目标距离和角度 [tgtrng,tgtang] = rangeangle(tgtmotion.InitialPosition,... sensormotion.InitialPosition); numtargets = length(target.MeanRCS); % 导向矢量和波束形成器 steeringvec = phased.SteeringVector('SensorArray',Array,... 'PropagationSpeed',lightspeed); beamformer = phased.PhaseShiftBeamformer('SensorArray',Array,... 'OperatingFrequency',fc,'PropagationSpeed',lightspeed,... 'DirectionSource','Input port'); % 传播信道 channel = phased.FreeSpace(... 'SampleRate',Fs,... 'TwoWayPropagation',true,... 'OperatingFrequency',fc); % 快时间网格和距离轴 fast_time_grid = unigrid(0, 1/Fs, 1/prf, '[)'); range_axis = lightspeed * fast_time_grid / 2; % 距离轴 % 接收脉冲存储 waveform_samples = length(Waveform()); rxpulses = zeros(waveform_samples, pulsenum, 'double'); % 辐射器和收集器 radiator = phased.Radiator(... 'Sensor',Array,... 'PropagationSpeed', lightspeed,... 'OperatingFrequency', fc,... 'CombineRadiatedSignals', true,... 'WeightsInputPort',true); collector = phased.Collector(... 'Sensor',Array,... 'PropagationSpeed', lightspeed,... 'OperatingFrequency', fc,... 'Wavefront', 'Plane',... 'WeightsInputPort',false); %% 回波模拟 for m = 1:pulsenum fprintf('脉冲数: %d \n', m); % 更新位置 [sensorpos,sensorvel] = sensormotion(1/prf); [tgtpos,tgtvel] = tgtmotion(1/prf); % 目标角度计算 [tgtrng,tgtang] = rangeangle(tgtpos,sensorpos); % 扫描角度和导向矢量 scanid = floor((m-1)/NumOfPulses) + 1; sv = steeringvec(fc,scangrid(scanid)); % w = conj(sv); w = conj(sv).*taper(:); % 发射信号和传播 pulse = Waveform(); % fprintf('波形生成功率: %.2f \n', sum(abs(pulse).^2)/400); [txsig,txstatus] = transmitter(pulse); % fprintf('发射波形功率: %.2f \n', sum(abs(txsig).^2)/400); txsig = radiator(txsig,tgtang,w); % fprintf('发射天线功率: %.2f \n', sum(abs(txsig).^2)/400); % fprintf('传输路径功率理论计算值: %.30f \n',sum(abs(txsig).^2)/400/((4*pi*19900/lambda).^4)); % fprintf('传输路径幅度理论计算值: %.30f \n',sum(abs(txsig))/400/((4*pi*19900/lambda).^2)); % a0=sum(abs(txsig).^2)/400/((4*pi*19900/lambda).^4); % a1=sum(abs(txsig))/400/((4*pi*19900/lambda).^2); txsig = channel(txsig,sensorpos,tgtpos,sensorvel,tgtvel); % fprintf('传输路径功率实验仿真值: %.30f \n', sum(abs(txsig).^2)/400); % fprintf('传输路径幅度实验仿真值: %.30f \n',sum(abs(txsig))/400); % b0=sum(abs(txsig).^2)/400; % b1=sum(abs(txsig))/400; % fprintf('功率衰减系数:%.30f \n',a0/b0); % fprintf('幅度衰减系数:%.30f \n',a1/b1); % 目标反射和接收处理 tgtsig = target(txsig); % fprintf('目标反射功率: %.30f \n', sum(abs(tgtsig).^2)/400); rxsig = collector(tgtsig,tgtang); % fprintf('接收天线功率: %.30f \n', sum(sum(abs(rxsig).^2))/400); rxsig = receiver(rxsig,~(txstatus>0)); % fprintf('接收波形功率: %.30f \n', sum(sum(abs(rxsig).^2))/400); rxpulses(:,m) = beamformer(rxsig,[scangrid(scanid);0]); % fprintf('接收平均功率: %.30f \n', sum(sum(abs(rxpulses).^2))/180); end % 脉冲压缩(提升距离分辨率) compressed = zeros(size(rxpulses)); for m = 1:pulsenum compressed(:,m) = Compression(rxpulses(:,m)); end % 转换为分贝幅度 magnitude_dB = 20*log10(abs(compressed) + 1e-10); % +1e-10避免log(0) % 绘制热力图 figure; imagesc(1:pulsenum, range_axis, magnitude_dB); axis xy; % 翻转y轴,使距离从下到上递增 xlabel('脉冲编号(慢时间)'); ylabel('距离(米)'); title('rxpulses的距离-慢时间热力图'); colorbar; % 颜色对应幅度(dB) colormap('jet'); % 红→黄→蓝表示强度从高到低 % 1. 确保已完成匹配滤波(使用前序步骤的compressed_pulses) % 2. 准备坐标轴数据 [X, Y] = meshgrid(1:pulsenum, range_axis); % X:脉冲编号(矩阵),Y:距离(矩阵) Z = 20*log10(abs(compressed) + 1e-12); % Z:幅度(dB),与X、Y维度匹配 % 3. 绘制三维网格图(兼顾细节与可读性) figure('Position', [100, 100, 1000, 800]); mesh(X, Y, Z, 'EdgeColor', 'interp', 'FaceColor', 'none'); % 线框插值着色,无填充 colormap('jet'); % 红→黄表示高幅度,蓝→青表示低幅度 colorbar; caxis([max(Z(:))-60, max(Z(:))]); % 限制动态范围,突出目标 % 4. 坐标轴与标题设置 xlabel('脉冲编号(慢时间)', 'FontSize', 10); ylabel('距离(米)', 'FontSize', 10); zlabel('幅度(dB)', 'FontSize', 10); title('匹配滤波后rxpulses的三维网格图(距离-脉冲编号-幅度)', 'FontSize', 12); view(30, 45); % 视角:方位角30°,仰角45°(可调整) grid on; axis tight; %% 距离测量 % 脉冲压缩后的信号在快时间轴(距离)上的峰值对应目标距离 % 1. 计算每个快时间点的最大幅度(跨所有脉冲) [max_amp_per_range, ~] = max(abs(compressed), [], 2); % 按快时间维度取最大值 % 2. 找到最大幅度对应的快时间索引 [~, peak_range_idx] = max(max_amp_per_range); % 目标距离的快时间索引 % 3. 转换为距离值(对应range_axis) measured_range = range_axis(peak_range_idx); % 4. 真实距离(参考目标初始位置) true_range = tgtrng; % 从rangeangle函数获取的初始真实距离 %% 角度测量 % 基于波束扫描,在目标距离处找到功率最大的扫描角度 % 1. 提取目标距离对应的快时间数据(跨所有脉冲) target_range_data = compressed(peak_range_idx, :); % 维度:[1, 总脉冲数] % 2. 按扫描角度分组(每个角度对应NumOfPulses个脉冲) angle_powers = zeros(1, numscans); % 存储每个角度的平均功率 for scan_idx = 1:numscans % 确定当前角度对应的脉冲索引范围 pulse_start = (scan_idx - 1) * NumOfPulses + 1; pulse_end = scan_idx * NumOfPulses; % 计算该角度下的平均功率(作为波束输出强度) angle_powers(scan_idx) = mean(abs(target_range_data(pulse_start:pulse_end)).^2); end % 3. 找到功率最大的角度(方位角) [~, peak_angle_idx] = max(angle_powers); % 最大功率对应的角度索引 measured_az = scangrid(peak_angle_idx); % 测量的方位角 % 4. 真实方位角(参考目标初始角度) true_az = tgtang(1); % tgtang为[方位角; 俯仰角],取方位角 %% 速度测量 % 基于慢时间(多脉冲)的多普勒频谱分析 % 1. 提取目标距离+角度对应的慢时间信号(多脉冲) pulse_start = (peak_angle_idx - 1) * NumOfPulses + 1; % 目标角度对应的脉冲起始索引 pulse_end = peak_angle_idx * NumOfPulses; % 脉冲结束索引 slow_time_signal = compressed(peak_range_idx, pulse_start:pulse_end); % 慢时间序列(维度:[1, NumOfPulses]) % 2. 慢时间FFT计算多普勒频谱 doppler_fft = fftshift(fft(slow_time_signal)); % 多普勒频谱(移位后中心为0频率) % 3. 构建多普勒频率轴(单位:Hz) doppler_freq = (-NumOfPulses/2 : NumOfPulses/2 - 1) * (prf / NumOfPulses); % 频率分辨率:prf/NumOfPulses % 4. 找到多普勒频谱峰值对应的频率 [~, peak_doppler_idx] = max(abs(doppler_fft)); % 峰值索引 measured_fd = doppler_freq(peak_doppler_idx); % 测量的多普勒频率 % 5. 计算径向速度 measured_velocity = (measured_fd * lambda) / 2; % 径向速度公式 % 6. 真实径向速度(目标速度在视线方向的分量) line_of_sight = (tgtpos - sensorpos) / norm(tgtpos - sensorpos); % 视线方向单位向量 true_velocity = dot(tgtvel, line_of_sight); % 径向速度=速度矢量·视线单位向量 %% 输出测量结果 fprintf('\n===== 测量结果 =====\n'); fprintf('距离测量:\n'); fprintf('真实距离:%.2f 米 | 测量距离:%.2f 米 | 误差:%.2f 米\n', ... true_range, measured_range, abs(measured_range - true_range)); fprintf('\n角度测量:\n'); fprintf('真实方位角:%.2f 度 | 测量方位角:%.2f 度 | 误差:%.2f 度\n', ... true_az, measured_az, abs(measured_az - true_az)); fprintf('\n速度测量:\n'); fprintf('真实径向速度:%.2f 米/秒 | 测量速度:%.2f 米/秒 | 误差:%.2f 米/秒\n', ... true_velocity, measured_velocity, abs(measured_velocity - true_velocity)); %% 测量结果可视化 % 1. 角度-功率图(验证角度测量) figure; plot(scangrid, 10*log10(angle_powers/max(angle_powers)), 'b-', 'LineWidth', 1.2); % 归一化功率(dB) hold on; plot(measured_az, 10*log10(angle_powers(peak_angle_idx)/max(angle_powers)), ... 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r', 'DisplayName', '测量角度'); plot(true_az, 0, 'go', 'MarkerSize', 8, 'MarkerFaceColor', 'g', 'DisplayName', '真实角度'); xlabel('方位角(度)'); ylabel('归一化功率(dB)'); title('角度测量:波束扫描功率分布'); legend(); grid on; % 2. 多普勒频谱图(验证速度测量) figure; plot(doppler_freq, 20*log10(abs(doppler_fft)/max(abs(doppler_fft))), 'b-', 'LineWidth', 1.2); % 归一化频谱(dB) hold on; plot(measured_fd, 20*log10(abs(doppler_fft(peak_doppler_idx))/max(abs(doppler_fft))), ... 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r', 'DisplayName', '测量频率'); true_fd = 2 * true_velocity / lambda; % 真实多普勒频率 plot(true_fd, 0, 'go', 'MarkerSize', 8, 'MarkerFaceColor', 'g', 'DisplayName', '真实频率'); xlabel('多普勒频率(Hz)'); ylabel('归一化幅度(dB)'); title('速度测量:多普勒频谱'); legend(); grid on; 代码测速结果存在严重速度模糊
最新发布
07-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值