空间调制信号检测算法实现

空间调制信号检测算法实现

空间调制(Spatial Modulation, SM)是一种MIMO传输技术,通过在多个发射天线中选择激活的天线来传递额外信息。

一、系统模型与基本检测算法

1.1 系统模型

% spatial_modulation_detection.m
% 空间调制信号检测算法实现

clear; clc; close all;

%% 1. 系统参数设置
Nt = 4;          % 发射天线数
Nr = 4;          % 接收天线数
M = 4;           % 调制阶数 (QPSK)
N_bits = 10000;  % 传输比特数
SNR_dB = 0:5:30; % 信噪比范围
N_SNR = length(SNR_dB);
N_trials = 1000; % 每个SNR点的蒙特卡洛仿真次数

% 调制映射 (QPSK)
constellation = (1/sqrt(2)) * [1+1j, 1-1j, -1+1j, -1-1j];
bit_map = [0 0; 0 1; 1 0; 1 1]; % 比特映射

% 存储误码率结果
BER_ML = zeros(1, N_SNR);
BER_ZF = zeros(1, N_SNR);
BER_MMSE = zeros(1, N_SNR);
BER_ML_approx = zeros(1, N_SNR);

%% 2. 空间调制信号生成函数
function [transmit_signal, active_antenna, symbol] = ...
    generate_SM_signal(bits, Nt, M, constellation)
    % 生成空间调制信号
    % 输入: bits - 输入比特流
    % 输出: transmit_signal - 发射信号向量 (Nt×1)
    %       active_antenna - 激活天线索引
    %       symbol - 发送的调制符号
    
    % 计算每SM符号携带的比特数
    bits_per_symbol = log2(Nt) + log2(M);
    n_symbols = length(bits) / bits_per_symbol;
    
    transmit_signal = zeros(Nt, n_symbols);
    active_antenna = zeros(1, n_symbols);
    symbol = zeros(1, n_symbols);
    
    for i = 1:n_symbols
        % 提取当前符号的比特
        start_idx = (i-1)*bits_per_symbol + 1;
        end_idx = i*bits_per_symbol;
        symbol_bits = bits(start_idx:end_idx);
        
        % 第一部分比特选择激活天线
        antenna_bits = symbol_bits(1:log2(Nt));
        antenna_idx = bi2de(antenna_bits', 'left-msb') + 1;
        
        % 第二部分比特选择调制符号
        symbol_bits_sm = symbol_bits(log2(Nt)+1:end);
        symbol_idx = bi2de(symbol_bits_sm', 'left-msb') + 1;
        symbol_val = constellation(symbol_idx);
        
        % 生成发射信号
        tx_vec = zeros(Nt, 1);
        tx_vec(antenna_idx) = symbol_val;
        
        transmit_signal(:, i) = tx_vec;
        active_antenna(i) = antenna_idx;
        symbol(i) = symbol_idx;
    end
end

二、最大似然(ML)检测算法

2.1 最优ML检测

%% 3. 最大似然检测算法
function [detected_antenna, detected_symbol, detected_bits] = ...
    ML_detector(received_signal, H, Nt, M, constellation, bit_map)
    % 最优ML检测器
    % 输入: received_signal - 接收信号向量
    %       H - 信道矩阵
    % 输出: 检测到的天线索引、符号索引和比特
    
    min_distance = inf;
    best_antenna = 1;
    best_symbol = 1;
    
    % 遍历所有可能的发射天线
    for ant_idx = 1:Nt
        % 遍历所有可能的调制符号
        for sym_idx = 1:M
            % 构造候选发射信号
            candidate_signal = zeros(Nt, 1);
            candidate_signal(ant_idx) = constellation(sym_idx);
            
            % 计算欧氏距离
            distance = norm(received_signal - H * candidate_signal)^2;
            
            % 更新最小距离
            if distance < min_distance
                min_distance = distance;
                best_antenna = ant_idx;
                best_symbol = sym_idx;
            end
        end
    end
    
    % 输出结果
    detected_antenna = best_antenna;
    detected_symbol = best_symbol;
    
    % 恢复比特
    antenna_bits = de2bi(best_antenna-1, log2(Nt), 'left-msb');
    symbol_bits = de2bi(best_symbol-1, log2(M), 'left-msb');
    detected_bits = [antenna_bits, symbol_bits];
end

2.2 低复杂度ML检测

function [detected_antenna, detected_symbol] = ...
    ML_low_complexity(received_signal, H, Nt, M, constellation)
    % 低复杂度ML检测
    % 基于QR分解的简化ML检测
    
    [Q, R] = qr(H);
    y_tilde = Q' * received_signal;
    
    min_distance = inf;
    best_antenna = 1;
    best_symbol = 1;
    
    for ant_idx = 1:Nt
        % 使用ZF预检测
        h_col = H(:, ant_idx);
        zf_symbol = (h_col' * received_signal) / (h_col' * h_col);
        
        % 符号检测
        [~, sym_idx] = min(abs(zf_symbol - constellation).^2);
        
        % 计算距离
        candidate = zeros(Nt, 1);
        candidate(ant_idx) = constellation(sym_idx);
        distance = norm(received_signal - H * candidate)^2;
        
        if distance < min_distance
            min_distance = distance;
            best_antenna = ant_idx;
            best_symbol = sym_idx;
        end
    end
    
    detected_antenna = best_antenna;
    detected_symbol = best_symbol;
end

三、线性检测算法

3.1 迫零(ZF)检测

%% 4. 迫零(ZF)检测
function [detected_antenna, detected_symbol] = ...
    ZF_detector(received_signal, H, Nt, M, constellation)
    % ZF检测器
    % 输入: received_signal - 接收信号
    %       H - 信道矩阵
    % 输出: 检测到的天线索引和符号索引
    
    % 计算ZF均衡矩阵
    W_ZF = (H' * H) \ H';  % 零陷矩阵
    
    % 均衡
    zf_output = W_ZF * received_signal;
    
    % 检测激活天线
    [~, ant_idx] = max(abs(zf_output));
    
    % 符号检测
    detected_symbol = zf_output(ant_idx);
    
    % 星座点映射
    [~, sym_idx] = min(abs(detected_symbol - constellation).^2);
    
    detected_antenna = ant_idx;
    detected_symbol = sym_idx;
end

3.2 最小均方误差(MMSE)检测

function [detected_antenna, detected_symbol] = ...
    MMSE_detector(received_signal, H, Nt, M, constellation, noise_power)
    % MMSE检测器
    % 输入: received_signal - 接收信号
    %       H - 信道矩阵
    %       noise_power - 噪声功率
    % 输出: 检测到的天线索引和符号索引
    
    % 计算MMSE均衡矩阵
    I = eye(Nt);
    W_MMSE = (H' * H + noise_power * I) \ H';
    
    % 均衡
    mmse_output = W_MMSE * received_signal;
    
    % 检测激活天线
    [~, ant_idx] = max(abs(mmse_output));
    
    % 符号检测
    detected_symbol = mmse_output(ant_idx);
    [~, sym_idx] = min(abs(detected_symbol - constellation).^2);
    
    detected_antenna = ant_idx;
    detected_symbol = sym_idx;
end

四、球形译码(SD)检测算法

4.1 球形译码实现

%% 5. 球形译码检测
function [detected_antenna, detected_symbol] = ...
    sphere_decoder(received_signal, H, Nt, M, constellation, radius)
    % 球形译码器
    % 输入: received_signal - 接收信号
    %       H - 信道矩阵
    %       radius - 搜索半径
    % 输出: 检测到的天线索引和符号索引
    
    [Q, R] = qr(H);
    y_tilde = Q' * received_signal;
    
    % 初始化
    level = Nt;
    path_metric = 0;
    best_metric = inf;
    best_path = zeros(Nt, 1);
    current_path = zeros(Nt, 1);
    
    % 递归搜索
    [best_path, best_metric] = SD_search(level, y_tilde, R, ...
        Nt, M, constellation, radius, path_metric, ...
        current_path, best_metric, best_path);
    
    % 解析结果
    [~, ant_idx] = max(abs(best_path));
    sym_val = best_path(ant_idx);
    [~, sym_idx] = min(abs(sym_val - constellation).^2);
    
    detected_antenna = ant_idx;
    detected_symbol = sym_idx;
end

function [best_path, best_metric] = SD_search(level, y_tilde, R, ...
    Nt, M, constellation, radius, path_metric, current_path, ...
    best_metric, best_path)
    % 球形译码递归搜索
    
    if level == 0
        % 到达叶节点
        if path_metric < best_metric
            best_metric = path_metric;
            best_path = current_path;
        end
        return;
    end
    
    % 计算Partial Distance (PD)
    if level == Nt
        PD = 0;
    else
        temp = 0;
        for k = level+1:Nt
            temp = temp + R(level, k) * current_path(k);
        end
        PD = y_tilde(level) - temp;
    end
    
    % 计算搜索边界
    d_prime_sq = radius^2 - path_metric;
    if d_prime_sq < 0
        return;  % 超出搜索半径
    end
    
    % 计算候选符号范围
    R_diag = R(level, level);
    lower_bound = (PD - sqrt(d_prime_sq)) / R_diag;
    upper_bound = (PD + sqrt(d_prime_sq)) / R_diag;
    
    % 在星座点中搜索
    for sym_idx = 1:M
        sym_val = constellation(sym_idx);
        
        % 检查是否在范围内
        if real(sym_val) >= real(lower_bound) && real(sym_val) <= real(upper_bound) && ...
           imag(sym_val) >= imag(lower_bound) && imag(sym_val) <= imag(upper_bound)
           
            % 更新路径
            current_path(level) = sym_val;
            
            % 更新部分距离
            distance = abs(y_tilde(level) - R_diag * sym_val)^2;
            if level < Nt
                for k = level+1:Nt
                    distance = distance + abs(y_tilde(k) - R(level, k) * sym_val)^2;
                end
            end
            
            new_metric = path_metric + distance;
            
            % 递归搜索下一层
            [best_path, best_metric] = SD_search(level-1, y_tilde, R, ...
                Nt, M, constellation, radius, new_metric, ...
                current_path, best_metric, best_path);
        end
    end
end

五、基于压缩感知的检测算法

5.1 稀疏重构检测

%% 6. 基于压缩感知的检测算法
function [detected_antenna, detected_symbol] = ...
    CS_detector(received_signal, H, Nt, M, constellation, lambda)
    % 压缩感知检测器
    % 使用LASSO算法进行稀疏重构
    
    % 构建过完备字典
    Phi = zeros(Nr, Nt * M);
    for ant_idx = 1:Nt
        for sym_idx = 1:M
            col_idx = (ant_idx-1)*M + sym_idx;
            Phi(:, col_idx) = H(:, ant_idx) * constellation(sym_idx);
        end
    end
    
    % LASSO稀疏重构
    x_est = lasso_reconstruction(received_signal, Phi, lambda);
    
    % 找到最大分量
    [~, max_idx] = max(abs(x_est));
    
    % 映射回天线和符号索引
    ant_idx = ceil(max_idx / M);
    sym_idx = mod(max_idx-1, M) + 1;
    
    detected_antenna = ant_idx;
    detected_symbol = sym_idx;
end

function x_est = lasso_reconstruction(y, A, lambda, max_iter)
    % LASSO重构算法
    % 输入: y - 观测向量
    %       A - 感知矩阵
    %       lambda - 正则化参数
    % 输出: x_est - 稀疏向量估计
    
    if nargin < 4
        max_iter = 1000;
    end
    
    [m, n] = size(A);
    x_est = zeros(n, 1);
    L = max(eig(A' * A));  % Lipschitz常数
    
    for iter = 1:max_iter
        % 梯度下降
        gradient = A' * (A * x_est - y);
        x_temp = x_est - (1/L) * gradient;
        
        % 软阈值算子
        x_est = sign(x_temp) .* max(abs(x_temp) - lambda/L, 0);
        
        % 收敛判断
        if norm(gradient) < 1e-6
            break;
        end
    end
end

六、深度学习检测方法

6.1 基于神经网络的检测器

# spatial_modulation_nn.py
# 基于深度学习的空间调制信号检测

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models
from sklearn.model_selection import train_test_split

class SM_Detector_NN:
    """基于神经网络的SM检测器"""
    
    def __init__(self, Nt, Nr, M, learning_rate=0.001):
        """
        初始化神经网络检测器
        
        参数:
            Nt: 发射天线数
            Nr: 接收天线数
            M: 调制阶数
        """
        self.Nt = Nt
        self.Nr = Nr
        self.M = M
        self.model = self._build_model()
        self.optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
        
    def _build_model(self):
        """构建神经网络模型"""
        model = models.Sequential([
            # 输入层: 接收信号的实部和虚部
            layers.Input(shape=(2*self.Nr,)),
            
            # 全连接层
            layers.Dense(256, activation='relu'),
            layers.BatchNormalization(),
            layers.Dropout(0.3),
            
            layers.Dense(128, activation='relu'),
            layers.BatchNormalization(),
            layers.Dropout(0.3),
            
            layers.Dense(64, activation='relu'),
            layers.BatchNormalization(),
            
            # 输出层: 天线选择概率 + 符号概率
            layers.Dense(self.Nt + self.M, activation='softmax')
        ])
        
        return model
    
    def preprocess_data(self, y, H):
        """预处理输入数据"""
        # 将复信号转换为实值表示
        y_real = np.concatenate([np.real(y), np.imag(y)], axis=-1)
        
        # 将信道信息也作为输入
        H_real = H.reshape(-1, 2*self.Nt*self.Nr)
        
        return np.concatenate([y_real, H_real], axis=-1)
    
    def train(self, X_train, y_train_antenna, y_train_symbol, 
              epochs=50, batch_size=32, validation_split=0.2):
        """训练神经网络"""
        
        # 准备标签
        y_antenna_onehot = tf.keras.utils.to_categorical(y_train_antenna, self.Nt)
        y_symbol_onehot = tf.keras.utils.to_categorical(y_train_symbol, self.M)
        y_train = np.concatenate([y_antenna_onehot, y_symbol_onehot], axis=1)
        
        # 编译模型
        self.model.compile(
            optimizer=self.optimizer,
            loss='categorical_crossentropy',
            metrics=['accuracy']
        )
        
        # 训练
        history = self.model.fit(
            X_train, y_train,
            epochs=epochs,
            batch_size=batch_size,
            validation_split=validation_split,
            verbose=1
        )
        
        return history
    
    def detect(self, y, H):
        """使用训练好的模型进行检测"""
        # 预处理输入
        X = self.preprocess_data(y.reshape(1, -1), H.reshape(1, -1))
        
        # 预测
        predictions = self.model.predict(X)
        
        # 解析预测结果
        antenna_probs = predictions[0, :self.Nt]
        symbol_probs = predictions[0, self.Nt:]
        
        # 选择最大概率
        antenna_idx = np.argmax(antenna_probs)
        symbol_idx = np.argmax(symbol_probs)
        
        return antenna_idx, symbol_idx

七、性能比较主程序

7.1 综合性能比较

%% 7. 主仿真程序
for snr_idx = 1:length(SNR_dB)
    SNR = 10^(SNR_dB(snr_idx)/10);
    noise_power = 1 / SNR;  % 假设信号功率归一化为1
    
    error_count_ML = 0;
    error_count_ZF = 0;
    error_count_MMSE = 0;
    error_count_ML_approx = 0;
    
    for trial = 1:N_trials
        %% 生成随机比特
        bits = randi([0, 1], 1, N_bits);
        
        %% 生成SM信号
        [tx_signal, true_antenna, true_symbol] = ...
            generate_SM_signal(bits, Nt, M, constellation);
        
        %% 生成信道矩阵 (瑞利衰落)
        H = (randn(Nr, Nt) + 1j*randn(Nr, Nt)) / sqrt(2);
        
        %% 生成噪声
        noise = sqrt(noise_power/2) * (randn(Nr, 1) + 1j*randn(Nr, 1));
        
        %% 接收信号
        rx_signal = H * tx_signal + noise;
        
        %% 使用不同检测器进行检测
        
        % 1. 最优ML检测
        [det_antenna_ML, det_symbol_ML] = ML_detector(...
            rx_signal, H, Nt, M, constellation, bit_map);
        
        % 2. ZF检测
        [det_antenna_ZF, det_symbol_ZF] = ZF_detector(...
            rx_signal, H, Nt, M, constellation);
        
        % 3. MMSE检测
        [det_antenna_MMSE, det_symbol_MMSE] = MMSE_detector(...
            rx_signal, H, Nt, M, constellation, noise_power);
        
        % 4. 低复杂度ML检测
        [det_antenna_ML_approx, det_symbol_ML_approx] = ...
            ML_low_complexity(rx_signal, H, Nt, M, constellation);
        
        %% 计算误码
        if det_antenna_ML ~= true_antenna || det_symbol_ML ~= true_symbol
            error_count_ML = error_count_ML + 1;
        end
        
        if det_antenna_ZF ~= true_antenna || det_symbol_ZF ~= true_symbol
            error_count_ZF = error_count_ZF + 1;
        end
        
        if det_antenna_MMSE ~= true_antenna || det_symbol_MMSE ~= true_symbol
            error_count_MMSE = error_count_MMSE + 1;
        end
        
        if det_antenna_ML_approx ~= true_antenna || det_symbol_ML_approx ~= true_symbol
            error_count_ML_approx = error_count_ML_approx + 1;
        end
    end
    
    %% 计算误码率
    BER_ML(snr_idx) = error_count_ML / (N_trials);
    BER_ZF(snr_idx) = error_count_ZF / (N_trials);
    BER_MMSE(snr_idx) = error_count_MMSE / (N_trials);
    BER_ML_approx(snr_idx) = error_count_ML_approx / (N_trials);
    
    fprintf('SNR = %d dB: ML BER = %.4f, ZF BER = %.4f, MMSE BER = %.4f, Approx ML BER = %.4f\n', ...
        SNR_dB(snr_idx), BER_ML(snr_idx), BER_ZF(snr_idx), ...
        BER_MMSE(snr_idx), BER_ML_approx(snr_idx));
end

%% 8. 绘制性能曲线
figure;
semilogy(SNR_dB, BER_ML, 'b-o', 'LineWidth', 2, 'MarkerSize', 8);
hold on;
semilogy(SNR_dB, BER_ZF, 'r-s', 'LineWidth', 2, 'MarkerSize', 8);
semilogy(SNR_dB, BER_MMSE, 'g-^', 'LineWidth', 2, 'MarkerSize', 8);
semilogy(SNR_dB, BER_ML_approx, 'm-d', 'LineWidth', 2, 'MarkerSize', 8);
grid on;
xlabel('SNR (dB)');
ylabel('Bit Error Rate (BER)');
legend('ML Detection', 'ZF Detection', 'MMSE Detection', 'Approx ML Detection');
title(['Spatial Modulation Detection Performance (Nt=' num2str(Nt) ...
    ', Nr=' num2str(Nr) ', M=' num2str(M) ')']);
set(gca, 'FontSize', 12);

参考代码 空间调制信号检测算法的基本程序 www.youwenfan.com/contentcsv/71784.html

八、基于消息传递的检测算法

8.1 近似消息传递(AMP)检测

%% 9. 近似消息传递检测算法
function [detected_antenna, detected_symbol, est_signal] = ...
    AMP_detector(received_signal, H, Nt, M, constellation, max_iter, tol)
    % AMP检测算法
    % 输入: received_signal - 接收信号
    %       H - 信道矩阵
    %       max_iter - 最大迭代次数
    %       tol - 收敛容差
    % 输出: 检测结果和估计信号
    
    if nargin < 6
        max_iter = 50;
    end
    if nargin < 7
        tol = 1e-6;
    end
    
    [Nr, Nt_total] = size(H);
    N = Nt_total;  % 稀疏向量的长度
    
    % AMP参数初始化
    x_est = zeros(N, 1);  % 信号估计
    z = received_signal;  % 残差
    gamma = zeros(N, 1);  % 辅助变量
    
    % 噪声方差估计
    noise_var = 0.01;
    
    for iter = 1:max_iter
        x_old = x_est;
        
        % 计算Onsager项
        if iter > 1
            tau_sq = norm(z)^2 / Nr;
            onsager = tau_sq * (x_est - gamma);
        else
            onsager = zeros(N, 1);
        end
        
        % 更新辅助变量
        gamma = x_est + H' * z - onsager;
        
        % 非线性估计器 (软阈值)
        x_est = nonlinear_estimator(gamma, noise_var, H, constellation, Nt, M);
        
        % 更新残差
        z = received_signal - H * x_est + ...
            (Nr/N) * z * mean(derivative_estimator(gamma, noise_var, H));
        
        % 检查收敛
        if norm(x_est - x_old) / norm(x_old) < tol
            break;
        end
    end
    
    % 从估计的稀疏向量中提取天线和符号信息
    [~, max_idx] = max(abs(x_est));
    ant_idx = ceil(max_idx / M);
    sym_idx = mod(max_idx-1, M) + 1;
    
    detected_antenna = ant_idx;
    detected_symbol = sym_idx;
    est_signal = x_est;
end

function x_est = nonlinear_estimator(gamma, noise_var, H, constellation, Nt, M)
    % 非线性估计器
    N = length(gamma);
    x_est = zeros(N, 1);
    
    for i = 1:N
        % 计算后验概率
        probs = zeros(1, length(constellation));
        for c = 1:length(constellation)
            symbol = constellation(c);
            probs(c) = exp(-abs(gamma(i) - symbol)^2 / (2*noise_var));
        end
        probs = probs / sum(probs);
        
        % 计算MMSE估计
        x_est(i) = sum(probs .* constellation);
    end
end

function deriv = derivative_estimator(gamma, noise_var, H)
    % 导数估计
    N = length(gamma);
    deriv = zeros(N, 1);
    
    for i = 1:N
        % 计算后验方差
        probs = zeros(1, length(constellation));
        for c = 1:length(constellation)
            symbol = constellation(c);
            probs(c) = exp(-abs(gamma(i) - symbol)^2 / (2*noise_var));
        end
        probs = probs / sum(probs);
        
        % 计算期望
        mean_est = sum(probs .* constellation);
        sec_moment = sum(probs .* abs(constellation).^2);
        
        deriv(i) = sec_moment - abs(mean_est)^2;
    end
end

九、计算复杂度分析

%% 10. 算法复杂度分析
function complexity_analysis(Nt, Nr, M)
    % 分析各种检测算法的复杂度
    
    fprintf('\n=== 复杂度分析 ===\n');
    fprintf('系统配置: Nt=%d, Nr=%d, M=%d\n\n', Nt, Nr, M);
    
    % ML检测复杂度
    ml_complexity = Nt * M;  % 需要遍历的组合数
    fprintf('ML检测: O(%d) 次距离计算\n', ml_complexity);
    
    % ZF检测复杂度
    zf_complexity = Nr^3 + Nt^3 + Nt*Nr;  % 矩阵求逆+乘法
    fprintf('ZF检测: O(Nr^3 + Nt^3) ≈ O(%d) 次浮点运算\n', zf_complexity);
    
    % MMSE检测复杂度
    mmse_complexity = Nr^3 + 2*Nt^3 + Nt*Nr;
    fprintf('MMSE检测: O(Nr^3 + 2Nt^3) ≈ O(%d) 次浮点运算\n', mmse_complexity);
    
    % 球形译码平均复杂度
    sd_avg_complexity = M * sqrt(Nt);  % 平均搜索节点数
    fprintf('球形译码(平均): O(M√Nt) ≈ O(%d) 次搜索\n', round(sd_avg_complexity));
    
    % AMP检测复杂度
    amp_complexity = 50 * (Nt * Nr + Nt * M);  % 50次迭代
    fprintf('AMP检测(50次迭代): O(%d) 次浮点运算\n', amp_complexity);
    
    % 神经网络检测复杂度
    nn_complexity = 256*2*Nr + 128*256 + 64*128 + (Nt+M)*64;  % 前向传播
    fprintf('神经网络检测: ≈ O(%d) 次乘加运算\n', nn_complexity);
end

十、实际应用建议

  1. 算法选择建议

    • 小规模系统(Nt≤4):使用最优ML检测
    • 中等规模系统(4<Nt≤8):使用球形译码或近似ML
    • 大规模系统(Nt>8):使用线性检测或深度学习检测
  2. 性能优化技巧

    • 利用信道矩阵的稀疏性
    • 实现并行计算加速
    • 使用查找表减少计算量
    • 结合信道编码提高性能
  3. 硬件实现考虑

    • FPGA实现适合并行算法
    • ASIC实现适合固定配置
    • GPU加速适合深度学习算法

专注于matlab/simulink,电子电路,编程