Análise de Algoritmos para Redução de PAPR em Sistemas OFDM e seu Impacto na Taxa de Erro de Bit

Um dos desafios inerentes aos sistemas de Transmissão por Divisão de Frequência Ortogonal (OFDM) é o elevado Pico de Relação Média de Potência (PAPR). Um PAPR alto pode conduzir a distorções não lineares nos amplificadores de potência e, consequentemente, aumentar a taxa de erro de bit (BER). Este artigo explora diversas técnicas para mitigar o PAPR em sistemas OFDM, apresentando implementações em MATLAB e análises de desempenho.

  1. O Problema do PAPR

1.1 Definição de PAPR

A Relação Pico-Média de Potência (PAPR) de um sinal s(t) é definida como:


PAPR(dB) = 10·log₁₀(max|s(t)|² / E[|s(t)|²])

Onde s(t) representa o sinal OFDM no domínio do tempo e E[·] denota o valor esperado.

1.2 Modelo de Sistema Adotado

  • Número de subportadoras (N): 64, 128, 256, etc.
  • Modulação: QPSK, 16QAM, 64QAM.
  • Fator de sobreamostragem (L): 4, para uma avaliação precisa do PAPR.
  1. Classificação de Algoritmos de Redução de PAPR

Os algoritmos para redução de PAPR podem ser categorizados da seguinte forma:

Categoria do Algoritmo Algoritmo Representativo Vantagens Desvantagens Impacto na BER
Clipping (Limitação) Clipping Duro, Clipping Suave Implementação simples Distorção não lineear Degradação notável
Probabilístico SLM (Selective Mapping), PTS (Partial Transmit Sequences) Sem distorção adicional Complexidade computacional, requer informação de banda lateral Sem degradação
Codificação Codificação em Bloco, Código de Golay Sem distorção Baixa eficiência espectral Sem degradação
Pré-distorção ACE (Average Coder Extension), TR (Tone Reservation) Bom desempenho Alta carga computacional Degradação leve
Entrelaçamento Reservas de Portadora, Expansão/Compressão Baixa complexidade Desempenho limitado Degradação leve
  1. Implementação Completa em MATLAB

3.1 Modelo Básico de Sistema OFDM

A classe OFDMSystem define a estrutura fundamental para simulações OFDM.


%% Modelo Básico de Sistema OFDM
classdef OFDMSystem < handle
    % Classe base para sistemas OFDM
    
    properties
        N = 64;             % Número de subportadoras
        Ncp = 16;           % Comprimento do prefixo cíclico
        M = 4;              % Ordem de modulação (QPSK=4, 16QAM=16, 64QAM=64)
        L = 4;              % Fator de sobreamostragem
        mod_type = 'QPSK';  % Tipo de modulação
        snr_db = 0:2:20;    % Faixa de SNR
        num_symbols = 1000; % Número de símbolos OFDM
    end
    
    methods
        function obj = OFDMSystem(varargin)
            % Construtor
            for i = 1:2:length(varargin)
                if isprop(obj, varargin{i})
                    obj.(varargin{i}) = varargin{i+1};
                end
            end
        end
        
        function [symbols, bits] = generate_data(obj)
            % Geração de dados aleatórios
            bits_per_symbol = log2(obj.M) * obj.N;
            total_bits = bits_per_symbol * obj.num_symbols;
            bits = randi([0, 1], total_bits, 1);
            
            % Modulação
            if strcmp(obj.mod_type, 'QPSK')
                symbols = pskmod(reshape(bits, 2, [])', 4, pi/4, 'gray');
            elseif strcmp(obj.mod_type, '16QAM')
                symbols = qammod(reshape(bits, 4, [])', 16, 'gray', 'InputType', 'bit');
            else
                symbols = qammod(reshape(bits, 6, [])', 64, 'gray', 'InputType', 'bit');
            end
            
            symbols = reshape(symbols, obj.N, obj.num_symbols);
        end
        
        function tx_signal = ofdm_modulate(obj, symbols)
            % Modulação OFDM
            [N_subcarriers, num_sym] = size(symbols);
            
            % Sobreamostragem
            if obj.L > 1
                padded_symbols = zeros(N_subcarriers*obj.L, num_sym);
                center_idx = floor(N_subcarriers/2);
                padded_symbols(1:center_idx, :) = symbols(1:center_idx, :);
                padded_symbols(end-center_idx+1:end, :) = symbols(center_idx+1:end, :);
            else
                padded_symbols = symbols;
            end
            
            % IFFT
            tx_signal = ifft(padded_symbols, N_subcarriers*obj.L, 1);
            
            % Adição de Prefixo Cíclico
            tx_signal = [tx_signal(end-obj.Ncp*obj.L+1:end, :); tx_signal];
        end
        
        function papr_db = calculate_papr(obj, signal)
            % Cálculo do PAPR
            signal_power = abs(signal).^2;
            peak_power = max(signal_power, [], 1);
            avg_power = mean(signal_power, 1);
            papr_linear = peak_power ./ avg_power;
            papr_db = 10*log10(papr_linear);
        end
        
        function ccdf = calculate_ccdf(obj, papr_values, threshold_db)
            % Cálculo da CCDF (Complementary Cumulative Distribution Function)
            papr_values = papr_values(:);
            ccdf = mean(papr_values > threshold_db);
        end
        
        function ber = simulate_ber(obj, snr_db_values)
            % Estrutura para simulação de BER
            % Subclasses devem sobrescrever este método
            error('O método simulate_ber deve ser implementado na subclasse.');
        end
    end
end

3.2 Algoritmos de Clipping

3.2.1 Clipping Duro

O método de clipping duro limita diretamente o envelope do sinal a um valor máximo predefinido.


%% Algoritmo de Clipping Duro
classdef HardClipping < OFDMSystem
    % Implementação do algoritmo de Clipping Duro
    
    properties
        clip_ratio = 0.8;  % Razão de limitação (CR)
    end
    
    methods
        function obj = HardClipping(varargin)
            obj = obj@OFDMSystem(varargin{:});
        end
        
        function clipped_signal = apply_clipping(obj, signal)
            % Aplica o clipping duro ao sinal
            amplitude = abs(signal);
            phase = angle(signal);
            
            % Define o limiar de clipping
            threshold = obj.clip_ratio * max(amplitude(:));
            
            % Aplica a limitação
            amplitude_clipped = min(amplitude, threshold);
            
            % Reconstrói o sinal
            clipped_signal = amplitude_clipped .* exp(1j*phase);
        end
        
        function ber = simulate_ber(obj, snr_db_values)
            % Simulação de BER com Clipping Duro
            ber = zeros(size(snr_db_values));
            
            for snr_idx = 1:length(snr_db_values)
                total_errors = 0;
                total_bits = 0;
                
                for sym_idx = 1:obj.num_symbols
                    % Geração de dados
                    bits_per_symbol = log2(obj.M) * obj.N;
                    bits = randi([0, 1], bits_per_symbol, 1);
                    
                    % Modulação
                    if strcmp(obj.mod_type, 'QPSK')
                        symbols = pskmod(reshape(bits, 2, [])', 4, pi/4, 'gray');
                    else
                        symbols = qammod(reshape(bits, 4, [])', 16, 'gray', 'InputType', 'bit');
                    end
                    
                    % Modulação OFDM
                    tx_signal = obj.ofdm_modulate(symbols);
                    
                    % Aplica Clipping
                    clipped_signal = obj.apply_clipping(tx_signal);
                    
                    % Adição de Ruído
                    signal_power = mean(abs(clipped_signal).^2);
                    noise_power = signal_power / (10^(snr_db_values(snr_idx)/10));
                    noise = sqrt(noise_power/2) * (randn(size(clipped_signal)) + 1j*randn(size(clipped_signal)));
                    rx_signal = clipped_signal + noise;
                    
                    % Demodulação OFDM
                    rx_symbols = obj.ofdm_demodulate(rx_signal); % Método assume-se existente na superclasse
                    
                    % Demodulação
                    if strcmp(obj.mod_type, 'QPSK')
                        rx_bits = pskdemod(rx_symbols, 4, pi/4, 'gray');
                    else
                        rx_bits = qamdemod(rx_symbols, 16, 'gray', 'OutputType', 'bit');
                    end
                    
                    % Cálculo de erros
                    errors = sum(bits(:) ~= rx_bits(:));
                    total_errors = total_errors + errors;
                    total_bits = total_bits + length(bits);
                end
                
                ber(snr_idx) = total_errors / total_bits;
            end
        end
        
        function plot_papr_performance(obj)
            % Geração de gráficos de desempenho de PAPR
            papr_original = [];
            papr_clipped = [];
            
            for i = 1:100
                % Geração de dados
                [symbols, ~] = obj.generate_data();
                tx_signal = obj.ofdm_modulate(symbols);
                
                % Cálculo de PAPR original
                papr_orig = obj.calculate_papr(tx_signal);
                papr_original = [papr_original, papr_orig];
                
                % Aplica clipping
                clipped_signal = obj.apply_clipping(tx_signal);
                papr_clip = obj.calculate_papr(clipped_signal);
                papr_clipped = [papr_clipped, papr_clip];
            end
            
            % Cálculo de CCDF
            threshold_db = 0:0.1:12;
            ccdf_original = zeros(size(threshold_db));
            ccdf_clipped = zeros(size(threshold_db));
            
            for i = 1:length(threshold_db)
                ccdf_original(i) = mean(papr_original > threshold_db(i));
                ccdf_clipped(i) = mean(papr_clipped > threshold_db(i));
            end
            
            % Plotagem
            figure('Position', [100, 100, 800, 600]);
            
            subplot(2,2,1);
            plot(threshold_db, ccdf_original, 'b-', 'LineWidth', 2);
            hold on;
            plot(threshold_db, ccdf_clipped, 'r--', 'LineWidth', 2);
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF = Pr(PAPR > PAPR_0)');
            title('Desempenho PAPR com Clipping Duro');
            legend(['Original (CR=1.0)', sprintf('Clipping (CR=%.1f)', obj.clip_ratio)]);
            grid on;
            
            subplot(2,2,2);
            [f_orig, x_orig] = ecdf(papr_original);
            [f_clip, x_clip] = ecdf(papr_clipped);
            plot(x_orig, 1-f_orig, 'b-', 'LineWidth', 2);
            hold on;
            plot(x_clip, 1-f_clip, 'r--', 'LineWidth', 2);
            xlabel('PAPR (dB)');
            ylabel('CCDF');
            title('Curvas ECDF');
            grid on;
            
            subplot(2,2,3);
            % Desempenho de BER
            snr_db = obj.snr_db;
            ber = obj.simulate_ber(snr_db);
            semilogy(snr_db, ber, 'b-o', 'LineWidth', 2);
            xlabel('SNR (dB)');
            ylabel('BER');
            title('Desempenho de BER com Clipping Duro');
            grid on;
            
            subplot(2,2,4);
            % Diagrama de constelação
            [symbols, ~] = obj.generate_data();
            tx_signal = obj.ofdm_modulate(symbols(:,1));
            clipped_signal = obj.apply_clipping(tx_signal);
            
            scatter(real(tx_signal(1:1000)), imag(tx_signal(1:1000)), 10, 'b.');
            hold on;
            scatter(real(clipped_signal(1:1000)), imag(clipped_signal(1:1000)), 10, 'r.');
            xlabel('Parte Real');
            ylabel('Parte Imaginária');
            title('Constelação no Domínio do Tempo');
            legend('Original', 'Após Clipping');
            axis equal;
            grid on;
            
            sgtitle(sprintf('Algoritmo de Clipping Duro (N=%d, %s)', obj.N, obj.mod_type));
        end
    end
end

3.2.2 Clipping Suave

O clipping suave aplica uma transição gradual em vez de uma limitação abrupta, visando reduzir a distorção gerada.


%% Algoritmo de Clipping Suave
classdef SoftClipping < OFDMSystem
    % Implementação do algoritmo de Clipping Suave
    
    properties
        clip_ratio = 0.8;      % Razão de limitação
        smooth_factor = 0.1;   % Fator de suavização
    end
    
    methods
        function clipped_signal = apply_soft_clipping(obj, signal)
            % Aplica o clipping suave ao sinal
            amplitude = abs(signal);
            phase = angle(signal);
            
            % Define o limiar
            threshold = obj.clip_ratio * max(amplitude(:));
            
            % Função de clipping suave
            amplitude_clipped = zeros(size(amplitude));
            
            idx_below = amplitude <= threshold;
            idx_above = amplitude > threshold;
            
            % Parte abaixo do limiar permanece inalterada
            amplitude_clipped(idx_below) = amplitude(idx_below);
            
            % Parte acima do limiar aplica o clipping suave
            excess = amplitude(idx_above) - threshold;
            amplitude_clipped(idx_above) = threshold + ...
                obj.smooth_factor * excess ./ (1 + obj.smooth_factor * excess/threshold);
            
            % Reconstrói o sinal
            clipped_signal = amplitude_clipped .* exp(1j*phase);
        end
    end
end

3.3 Algoritmos Probabilísticos

3.3.1 Selective Mapping (SLM)

O SLM gera múltiplos sinais OFDM a partir dos mesmos dados de entrada, rotacionando as fases das subportadoras. O sinal com o menor PAPR é selecionado para transmissão, exigindo o envio de informação de controle para a reconstrução.


%% Algoritmo Selective Mapping (SLM)
classdef SLM < OFDMSystem
    % Implementação do algoritmo SLM
    
    properties
        U = 4;              % Número de sequências de fase
        phase_sequences;    % Sequências de fase geradas
        selected_indices;   % Índices das sequências selecionadas
    end
    
    methods
        function obj = SLM(varargin)
            obj = obj@OFDMSystem(varargin{:});
            obj.generate_phase_sequences();
        end
        
        function generate_phase_sequences(obj)
            % Geração de sequências de fase aleatórias
            obj.phase_sequences = exp(1j * 2*pi * rand(obj.N, obj.U));
        end
        
        function [tx_signal, best_idx] = apply_slm(obj, symbols)
            % Aplica o algoritmo SLM
            papr_values = zeros(1, obj.U);
            candidate_signals = cell(1, obj.U);
            
            for u = 1:obj.U
                % Aplica rotação de fase
                rotated_symbols = symbols .* obj.phase_sequences(:, u);
                
                % Modulação OFDM
                candidate = obj.ofdm_modulate(rotated_symbols);
                candidate_signals{u} = candidate;
                
                % Cálculo de PAPR
                papr_values(u) = mean(obj.calculate_papr(candidate));
            end
            
            % Seleciona o sinal com menor PAPR
            [~, best_idx] = min(papr_values);
            tx_signal = candidate_signals{best_idx};
            obj.selected_indices = best_idx;
        end
        
        function ber = simulate_ber_with_slm(obj, snr_db_values)
            % Simulação de BER para SLM
            ber = zeros(size(snr_db_values));
            
            for snr_idx = 1:length(snr_db_values)
                total_errors = 0;
                total_bits = 0;
                
                for sym_idx = 1:obj.num_symbols
                    % Geração de dados
                    bits_per_symbol = log2(obj.M) * obj.N;
                    bits = randi([0, 1], bits_per_symbol, 1);
                    
                    % Modulação
                    if strcmp(obj.mod_type, 'QPSK')
                        symbols = pskmod(reshape(bits, 2, [])', 4, pi/4, 'gray');
                    else
                        symbols = qammod(reshape(bits, 4, [])', 16, 'gray', 'InputType', 'bit');
                    end
                    
                    % Aplica SLM
                    [tx_signal, best_idx] = obj.apply_slm(symbols);
                    
                    % Transmissão de informação de banda lateral (ideal)
                    side_info = de2bi(best_idx-1, ceil(log2(obj.U)), 'left-msb')';
                    
                    % Adição de Ruído
                    signal_power = mean(abs(tx_signal).^2);
                    noise_power = signal_power / (10^(snr_db_values(snr_idx)/10));
                    noise = sqrt(noise_power/2) * (randn(size(tx_signal)) + 1j*randn(size(tx_signal)));
                    rx_signal = tx_signal + noise;
                    
                    % Demodulação OFDM
                    rx_symbols_pre = obj.ofdm_demodulate(rx_signal); % Método assume-se existente na superclasse
                    
                    % Aplica rotação inversa de fase (assumindo informação de banda lateral correta)
                    rx_symbols = rx_symbols_pre .* conj(obj.phase_sequences(:, best_idx));
                    
                    % Demodulação
                    if strcmp(obj.mod_type, 'QPSK')
                        rx_bits = pskdemod(rx_symbols, 4, pi/4, 'gray');
                    else
                        rx_bits = qamdemod(rx_symbols, 16, 'gray', 'OutputType', 'bit');
                    end
                    
                    % Cálculo de erros
                    errors = sum(bits(:) ~= rx_bits(:));
                    total_errors = total_errors + errors;
                    total_bits = total_bits + length(bits);
                end
                
                ber(snr_idx) = total_errors / total_bits;
            end
        end
        
        function plot_slm_performance(obj)
            % Geração de gráficos de desempenho SLM
            papr_original = [];
            papr_slm = [];
            
            for i = 1:100
                [symbols, ~] = obj.generate_data();
                
                % OFDM Original
                tx_original = obj.ofdm_modulate(symbols);
                papr_orig = obj.calculate_papr(tx_original);
                papr_original = [papr_original, papr_orig];
                
                % SLM
                [tx_slm, ~] = obj.apply_slm(symbols);
                papr_s = obj.calculate_papr(tx_slm);
                papr_slm = [papr_slm, papr_s];
            end
            
            % Cálculo de CCDF
            threshold_db = 0:0.1:12;
            ccdf_original = zeros(size(threshold_db));
            ccdf_slm = zeros(size(threshold_db));
            
            for i = 1:length(threshold_db)
                ccdf_original(i) = mean(papr_original > threshold_db(i));
                ccdf_slm(i) = mean(papr_slm > threshold_db(i));
            end
            
            % Plotagem
            figure('Position', [100, 100, 1000, 400]);
            
            subplot(1,2,1);
            plot(threshold_db, ccdf_original, 'b-', 'LineWidth', 2);
            hold on;
            plot(threshold_db, ccdf_slm, 'r--', 'LineWidth', 2);
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF = Pr(PAPR > PAPR_0)');
            title(sprintf('Desempenho PAPR com SLM (U=%d)', obj.U));
            legend('Original', 'SLM');
            grid on;
            
            subplot(1,2,2);
            % Comparação com diferentes valores de U
            U_values = [2, 4, 8, 16];
            colors = {'b-', 'r--', 'g-.', 'm:'};
            
            for u_idx = 1:length(U_values)
                obj.U = U_values(u_idx);
                obj.generate_phase_sequences();
                
                papr_slm_u = [];
                for i = 1:50
                    [symbols, ~] = obj.generate_data();
                    [tx_slm, ~] = obj.apply_slm(symbols);
                    papr_s = obj.calculate_papr(tx_slm);
                    papr_slm_u = [papr_slm_u, papr_s];
                end
                
                ccdf_slm_u = zeros(size(threshold_db));
                for i = 1:length(threshold_db)
                    ccdf_slm_u(i) = mean(papr_slm_u > threshold_db(i));
                end
                
                plot(threshold_db, ccdf_slm_u, colors{u_idx}, 'LineWidth', 2);
                hold on;
            end
            
            plot(threshold_db, ccdf_original, 'k-', 'LineWidth', 3);
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF');
            title('Desempenho SLM com diferentes U');
            legend(arrayfun(@(x) sprintf('U=%d', x), U_values, 'UniformOutput', false), 'Original');
            grid on;
            
            sgtitle(sprintf('Algoritmo Selective Mapping (SLM) (N=%d, %s)', obj.N, obj.mod_type));
        end
    end
end

3.3.2 Partial Transmit Sequences (PTS)

O PTS divide o sinal OFDM em subconjuntos, aplica rotações de fase a cada subconjunto e recombina-os para minimizar o PAPR. Asim como o SLM, requer informação de banda lateral.


%% Algoritmo Partial Transmit Sequences (PTS)
classdef PTS < OFDMSystem
    % Implementação do algoritmo PTS
    
    properties
        V = 4;              % Número de partições
        W = 4;              % Número de fatores de fase
        phase_factors;      % Conjunto de fatores de fase
        partition_method = 'adjacent';  % Método de particionamento
    end
    
    methods
        function obj = PTS(varargin)
            obj = obj@OFDMSystem(varargin{:});
            obj.generate_phase_factors();
        end
        
        function generate_phase_factors(obj)
            % Geração de fatores de fase
            obj.phase_factors = exp(1j * 2*pi/obj.W * (0:obj.W-1));
        end
        
        function [tx_signal, best_phase] = apply_pts(obj, symbols)
            % Aplica o algoritmo PTS
            
            % Particionamento das subportadoras
            switch obj.partition_method
                case 'adjacent'
                    % Particionamento adjacente
                    subcarriers_per_part = floor(obj.N / obj.V);
                    partitions = zeros(obj.N, obj.V);
                    for v = 1:obj.V
                        start_idx = (v-1)*subcarriers_per_part + 1;
                        end_idx = min(v*subcarriers_per_part, obj.N);
                        partitions(start_idx:end_idx, v) = 1;
                    end
                    
                case 'interleaved'
                    % Particionamento entrelaçado
                    partitions = zeros(obj.N, obj.V);
                    for n = 1:obj.N
                        v = mod(n-1, obj.V) + 1;
                        partitions(n, v) = 1;
                    end
                    
                case 'pseudo'
                    % Particionamento pseudo-aleatório
                    partitions = zeros(obj.N, obj.V);
                    for n = 1:obj.N
                        v = randi([1, obj.V]);
                        partitions(n, v) = 1;
                    end
            end
            
            % Geração de sequências parciais
            part_sequences = cell(1, obj.V);
            for v = 1:obj.V
                part_symbols = symbols .* partitions(:, v);
                part_sequences{v} = obj.ofdm_modulate(part_symbols);
            end
            
            % Busca pela combinação ótima de fases
            min_papr = inf;
            best_signal = [];
            best_phase = ones(1, obj.V);
            
            % Itera sobre todas as combinações de fases
            phase_combinations = obj.generate_all_combinations(obj.V, obj.W);
            
            for combo_idx = 1:size(phase_combinations, 1)
                phase_combo = phase_combinations(combo_idx, :);
                
                % Combina os sinais
                combined_signal = zeros(size(part_sequences{1}));
                for v = 1:obj.V
                    phase_factor = obj.phase_factors(phase_combo(v));
                    combined_signal = combined_signal + phase_factor * part_sequences{v};
                end
                
                % Cálculo de PAPR
                papr = mean(obj.calculate_papr(combined_signal));
                
                if papr < min_papr
                    min_papr = papr;
                    best_signal = combined_signal;
                    best_phase = phase_combo;
                end
            end
            
            tx_signal = best_signal;
        end
        
        function combinations = generate_all_combinations(obj, V, W)
            % Geração de todas as combinações de fases
            indices = 1:W;
            combs = cell(V, 1);
            [combs{:}] = ndgrid(indices);
            combinations = reshape(cat(V+1, combs{:}), [], V);
        end
        
        function plot_pts_performance(obj)
            % Geração de gráficos de desempenho PTS
            papr_original = [];
            papr_pts = [];
            
            for i = 1:50
                [symbols, ~] = obj.generate_data();
                
                % OFDM Original
                tx_original = obj.ofdm_modulate(symbols);
                papr_orig = obj.calculate_papr(tx_original);
                papr_original = [papr_original, papr_orig];
                
                % PTS
                [tx_pts, ~] = obj.apply_pts(symbols);
                papr_p = obj.calculate_papr(tx_pts);
                papr_pts = [papr_pts, papr_p];
            end
            
            % Cálculo de CCDF
            threshold_db = 0:0.1:12;
            ccdf_original = zeros(size(threshold_db));
            ccdf_pts = zeros(size(threshold_db));
            
            for i = 1:length(threshold_db)
                ccdf_original(i) = mean(papr_original > threshold_db(i));
                ccdf_pts(i) = mean(papr_pts > threshold_db(i));
            end
            
            % Plotagem
            figure('Position', [100, 100, 1200, 400]);
            
            subplot(1,3,1);
            plot(threshold_db, ccdf_original, 'b-', 'LineWidth', 2);
            hold on;
            plot(threshold_db, ccdf_pts, 'r--', 'LineWidth', 2);
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF');
            title(sprintf('Desempenho PAPR com PTS (V=%d, W=%d)', obj.V, obj.W));
            legend('Original', 'PTS');
            grid on;
            
            subplot(1,3,2);
            % Comparação com diferentes métodos de particionamento
            methods = {'adjacent', 'interleaved', 'pseudo'};
            colors = {'b-', 'r--', 'g-.'};
            
            for m_idx = 1:length(methods)
                obj.partition_method = methods{m_idx};
                
                papr_pts_m = [];
                for i = 1:30
                    [symbols, ~] = obj.generate_data();
                    [tx_pts, ~] = obj.apply_pts(symbols);
                    papr_p = obj.calculate_papr(tx_pts);
                    papr_pts_m = [papr_pts_m, papr_p];
                end
                
                ccdf_pts_m = zeros(size(threshold_db));
                for i = 1:length(threshold_db)
                    ccdf_pts_m(i) = mean(papr_pts_m > threshold_db(i));
                end
                
                plot(threshold_db, ccdf_pts_m, colors{m_idx}, 'LineWidth', 2);
                hold on;
            end
            
            plot(threshold_db, ccdf_original, 'k-', 'LineWidth', 3);
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF');
            title('Comparação de Métodos de Particionamento');
            legend(methods{:}, 'Original');
            grid on;
            
            subplot(1,3,3);
            % Análise de complexidade computacional
            V_values = [2, 4, 8];
            W_values = [2, 4];
            
            complexity = zeros(length(V_values), length(W_values));
            papr_gain = zeros(length(V_values), length(W_values));
            
            for v_idx = 1:length(V_values)
                for w_idx = 1:length(W_values)
                    obj.V = V_values(v_idx);
                    obj.W = W_values(w_idx);
                    obj.generate_phase_factors();
                    
                    % Complexidade = W^V
                    complexity(v_idx, w_idx) = obj.W^obj.V;
                    
                    % Ganho de PAPR
                    papr_pts_test = [];
                    for i = 1:20
                        [symbols, ~] = obj.generate_data();
                        [tx_pts, ~] = obj.apply_pts(symbols);
                        papr_p = obj.calculate_papr(tx_pts);
                        papr_pts_test = [papr_pts_test, papr_p];
                    end
                    
                    papr_gain(v_idx, w_idx) = mean(papr_original(1:20)) - mean(papr_pts_test);
                end
            end
            
            % Gráfico de barras 3D
            [X, Y] = meshgrid(1:length(W_values), 1:length(V_values));
            bar3(complexity);
            xlabel('W');
            ylabel('V');
            zlabel('Complexidade Computacional');
            title('Análise de Complexidade Computacional PTS');
            set(gca, 'XTickLabel', W_values);
            set(gca, 'YTickLabel', V_values);
            grid on;
            
            sgtitle(sprintf('Algoritmo Partial Transmit Sequences (PTS) (N=%d, %s)', obj.N, obj.mod_type));
        end
    end
end

3.4 Algoritmo de Expansão/Compressão (Companding)

O Companding (μ-law) comprime a faixa dinâmica do sinal antes da transmissão e o expande na recepção, o que pode reduzir o PAPR.


%% Algoritmo de Companding μ-law
classdef MuLawCompanding < OFDMSystem
    % Implementação do algoritmo de Companding μ-law
    
    properties
        mu = 255;           % Parâmetro de companding
    end
    
    methods
        function compressed = compress(obj, signal)
            % Compressão do sinal
            max_amplitude = max(abs(signal(:)));
            normalized = signal / max_amplitude;
            
            compressed = (log(1 + obj.mu * abs(normalized)) / log(1 + obj.mu)) .* ...
                exp(1j * angle(normalized)) * max_amplitude;
        end
        
        function expanded = expand(obj, signal)
            % Expansão do sinal
            max_amplitude = max(abs(signal(:)));
            normalized = signal / max_amplitude;
            
            expanded = ((1/obj.mu) * ((1 + obj.mu).^abs(normalized) - 1)) .* ...
                exp(1j * angle(normalized)) * max_amplitude;
        end
        
        function plot_companding_performance(obj)
            % Geração de gráficos de desempenho do Companding
            papr_original = [];
            papr_companded = [];
            
            for i = 1:100
                [symbols, ~] = obj.generate_data();
                tx_original = obj.ofdm_modulate(symbols);
                
                % Companding
                tx_companded = obj.compress(tx_original);
                
                papr_orig = obj.calculate_papr(tx_original);
                papr_comp = obj.calculate_papr(tx_companded);
                
                papr_original = [papr_original, papr_orig];
                papr_companded = [papr_companded, papr_comp];
            end
            
            % Cálculo de CCDF
            threshold_db = 0:0.1:12;
            ccdf_original = zeros(size(threshold_db));
            ccdf_companded = zeros(size(threshold_db));
            
            for i = 1:length(threshold_db)
                ccdf_original(i) = mean(papr_original > threshold_db(i));
                ccdf_companded(i) = mean(papr_companded > threshold_db(i));
            end
            
            % Plotagem
            figure('Position', [100, 100, 800, 600]);
            
            subplot(2,2,1);
            plot(threshold_db, ccdf_original, 'b-', 'LineWidth', 2);
            hold on;
            plot(threshold_db, ccdf_companded, 'r--', 'LineWidth', 2);
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF');
            title(sprintf('Desempenho PAPR Companding μ-law (μ=%.0f)', obj.mu));
            legend('Original', 'Após Companding');
            grid on;
            
            subplot(2,2,2);
            % Comparação com diferentes valores de μ
            mu_values = [1, 10, 100, 255];
            colors = {'b-', 'r--', 'g-.', 'm:'};
            
            for mu_idx = 1:length(mu_values)
                obj.mu = mu_values(mu_idx);
                
                papr_mu = [];
                for i = 1:50
                    [symbols, ~] = obj.generate_data();
                    tx_signal = obj.ofdm_modulate(symbols);
                    tx_comp = obj.compress(tx_signal);
                    papr_c = obj.calculate_papr(tx_comp);
                    papr_mu = [papr_mu, papr_c];
                end
                
                ccdf_mu = zeros(size(threshold_db));
                for i = 1:length(threshold_db)
                    ccdf_mu(i) = mean(papr_mu > threshold_db(i));
                end
                
                plot(threshold_db, ccdf_mu, colors{mu_idx}, 'LineWidth', 2);
                hold on;
            end
            
            plot(threshold_db, ccdf_original, 'k-', 'LineWidth', 3);
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF');
            title('Comparação de Desempenho com Diferentes μ');
            legend(arrayfun(@(x) sprintf('μ=%.0f', x), mu_values, 'UniformOutput', false), 'Original');
            grid on;
            
            subplot(2,2,3);
            % Curva característica do Companding
            x = linspace(0, 1, 1000);
            for mu_idx = 1:length(mu_values)
                mu = mu_values(mu_idx);
                y = log(1 + mu * x) / log(1 + mu);
                plot(x, y, colors{mu_idx}, 'LineWidth', 2);
                hold on;
            end
            plot(x, x, 'k--', 'LineWidth', 1);
            xlabel('Entrada Normalizada');
            ylabel('Saída Normalizada');
            title('Característica do Companding μ-law');
            legend(arrayfun(@(x) sprintf('μ=%.0f', x), mu_values, 'UniformOutput', false), 'Linear');
            grid on;
            
            subplot(2,2,4);
            % Desempenho de BER
            snr_db = 0:2:20;
            ber_original = zeros(size(snr_db));
            ber_companded = zeros(size(snr_db));
            
            for snr_idx = 1:length(snr_db)
                ber_o = 0;
                ber_c = 0;
                total_bits = 0;
                
                for sym_idx = 1:10
                    % Geração de dados
                    bits_per_symbol = log2(obj.M) * obj.N;
                    bits = randi([0, 1], bits_per_symbol, 1);
                    
                    if strcmp(obj.mod_type, 'QPSK')
                        symbols = pskmod(reshape(bits, 2, [])', 4, pi/4, 'gray');
                    else
                        symbols = qammod(reshape(bits, 4, [])', 16, 'gray', 'InputType', 'bit');
                    end
                    
                    % OFDM Original
                    tx_original = obj.ofdm_modulate(symbols);
                    signal_power = mean(abs(tx_original).^2);
                    noise_power = signal_power / (10^(snr_db(snr_idx)/10));
                    noise = sqrt(noise_power/2) * (randn(size(tx_original)) + 1j*randn(size(tx_original)));
                    rx_original = tx_original + noise;
                    rx_symbols_o = obj.ofdm_demodulate(rx_original);
                    
                    % OFDM com Companding
                    tx_comp = obj.compress(tx_original);
                    signal_power_c = mean(abs(tx_comp).^2);
                    noise_power_c = signal_power_c / (10^(snr_db(snr_idx)/10));
                    noise_c = sqrt(noise_power_c/2) * (randn(size(tx_comp)) + 1j*randn(size(tx_comp)));
                    rx_comp = tx_comp + noise_c;
                    rx_expanded = obj.expand(rx_comp);
                    rx_symbols_c = obj.ofdm_demodulate(rx_expanded);
                    
                    % Demodulação
                    if strcmp(obj.mod_type, 'QPSK')
                        rx_bits_o = pskdemod(rx_symbols_o, 4, pi/4, 'gray');
                        rx_bits_c = pskdemod(rx_symbols_c, 4, pi/4, 'gray');
                    else
                        rx_bits_o = qamdemod(rx_symbols_o, 16, 'gray', 'OutputType', 'bit');
                        rx_bits_c = qamdemod(rx_symbols_c, 16, 'gray', 'OutputType', 'bit');
                    end
                    
                    errors_o = sum(bits ~= rx_bits_o);
                    errors_c = sum(bits ~= rx_bits_c);
                    
                    ber_o = ber_o + errors_o;
                    ber_c = ber_c + errors_c;
                    total_bits = total_bits + length(bits);
                end
                
                ber_original(snr_idx) = ber_o / total_bits;
                ber_companded(snr_idx) = ber_c / total_bits;
            end
            
            semilogy(snr_db, ber_original, 'b-o', 'LineWidth', 2);
            hold on;
            semilogy(snr_db, ber_companded, 'r-s', 'LineWidth', 2);
            xlabel('SNR (dB)');
            ylabel('BER');
            title('Impacto do Companding no BER');
            legend('Original', 'Companding');
            grid on;
            
            sgtitle('Análise de Desempenho do Companding μ-law');
        end
    end
end
  1. Comparação Abrangente de Desempenho

4.1 Comparação de Desempenho de Algoritmos

Esta seção compara o desempenho de PAPR, complexidade e outras métricas de vários algoritmos.


%% Comparação Abrangente de Algoritmos
classdef PAPRComparison
    % Comparação abrangente de algoritmos de redução de PAPR
    
    methods (Static)
        function compare_all_algorithms()
            % Compara todos os algoritmos
            
            % Configuração dos parâmetros
            N = 64;
            M = 4;  % QPSK
            num_symbols = 1000;
            L = 4;
            
            % Criação de instâncias dos algoritmos
            ofdm_base = OFDMSystem('N', N, 'M', M, 'L', L, 'num_symbols', num_symbols);
            
            % Clipping Duro
            clipping = HardClipping('N', N, 'M', M, 'L', L, 'num_symbols', num_symbols, 'clip_ratio', 0.8);
            
            % SLM
            slm = SLM('N', N, 'M', M, 'L', L, 'num_symbols', num_symbols, 'U', 4);
            
            % PTS
            pts = PTS('N', N, 'M', M, 'L', L, 'num_symbols', num_symbols, 'V', 4, 'W', 4);
            
            % Companding
            companding = MuLawCompanding('N', N, 'M', M, 'L', L, 'num_symbols', num_symbols, 'mu', 255);
            
            % Geração de dados
            [symbols, bits] = ofdm_base.generate_data();
            
            % Cálculo de PAPR para cada algoritmo
            papr_results = struct();
            
            % OFDM Original
            tx_original = ofdm_modulate(ofdm_base, symbols);
            papr_results.original = calculate_papr(ofdm_base, tx_original);
            
            % Clipping Duro
            tx_clipped = apply_clipping(clipping, tx_original);
            papr_results.clipping = calculate_papr(clipping, tx_clipped);
            
            % SLM
            [tx_slm, ~] = apply_slm(slm, symbols);
            papr_results.slm = calculate_papr(slm, tx_slm);
            
            % PTS
            [tx_pts, ~] = apply_pts(pts, symbols);
            papr_results.pts = calculate_papr(pts, tx_pts);
            
            % Companding
            tx_comp = compress(companding, tx_original);
            papr_results.companding = calculate_papr(companding, tx_comp);
            
            % Plotagem da comparação de CCDF
            figure('Position', [100, 100, 1000, 800]);
            
            subplot(2,2,1);
            threshold_db = 0:0.1:12;
            algorithms = fieldnames(papr_results);
            colors = {'k-', 'b-', 'r--', 'g-.', 'm:', 'c-'};
            
            for i = 1:length(algorithms)
                papr_data = papr_results.(algorithms{i});
                ccdf = zeros(size(threshold_db));
                
                for t = 1:length(threshold_db)
                    ccdf(t) = mean(papr_data > threshold_db(t));
                end
                
                plot(threshold_db, ccdf, colors{i}, 'LineWidth', 2);
                hold on;
            end
            
            xlabel('PAPR_0 (dB)');
            ylabel('CCDF = Pr(PAPR > PAPR_0)');
            title('Comparação de Desempenho PAPR dos Algoritmos');
            legend(algorithms, 'Location', 'northeast');
            grid on;
            
            subplot(2,2,2);
            % Comparação de PAPR médio
            avg_papr = zeros(length(algorithms), 1);
            std_papr = zeros(length(algorithms), 1);
            
            for i = 1:length(algorithms)
                avg_papr(i) = mean(papr_results.(algorithms{i}));
                std_papr(i) = std(papr_results.(algorithms{i}));
            end
            
            bar(1:length(algorithms), avg_papr);
            hold on;
            errorbar(1:length(algorithms), avg_papr, std_papr, 'k.', 'LineWidth', 2);
            set(gca, 'XTickLabel', algorithms);
            xtickangle(45);
            ylabel('PAPR Médio (dB)');
            title('Comparação de PAPR Médio');
            grid on;
            
            subplot(2,2,3);
            % Ganho de PAPR
            papr_gain = avg_papr(1) - avg_papr;
            bar(1:length(algorithms), papr_gain);
            set(gca, 'XTickLabel', algorithms);
            xtickangle(45);
            ylabel('Ganho de PAPR (dB)');
            title('Ganho de PAPR em Relação ao OFDM Original');
            grid on;
            
            subplot(2,2,4);
            % Comparação de complexidade computacional
            complexity = [
                1;              % Original
                N;              % Clipping
                slm.U * N;      % SLM
                pts.W^pts.V;    % PTS
                N               % Companding
            ];
            
            bar(1:length(algorithms), log10(complexity));
            set(gca, 'XTickLabel', algorithms);
            xtickangle(45);
            ylabel('log10(Complexidade Computacional)');
            title('Comparação de Complexidade Computacional');
            grid on;
            
            sgtitle('Comparação Abrangente dos Algoritmos de Redução de PAPR OFDM');
            
            % Exibe a tabela estatística
            fprintf('\n=== Estatísticas de Desempenho dos Algoritmos ===\n');
            fprintf('%-15s %-10s %-10s %-10s %-10s\n', ...
                'Algoritmo', 'PAPR Médio', 'Desvio Padrão', 'Ganho PAPR', 'Complexidade');
            fprintf('%s\n', repmat('-', 60, 1));
            
            for i = 1:length(algorithms)
                fprintf('%-15s %-10.2f %-10.2f %-10.2f %-10.0f\n', ...
                    algorithms{i}, avg_papr(i), std_papr(i), ...
                    papr_gain(i), complexity(i));
            end
        end
        
        function ber_comparison()
            % Comparação de desempenho de BER
            N = 64;
            M = 4;
            num_symbols = 100;
            snr_db = 0:2:20;
            
            % Criação de instâncias dos algoritmos
            clipping = HardClipping('N', N, 'M', M, 'num_symbols', num_symbols);
            slm = SLM('N', N, 'M', M, 'num_symbols', num_symbols, 'U', 4);
            pts = PTS('N', N, 'M', M, 'num_symbols', num_symbols, 'V', 4, 'W', 4);
            companding = MuLawCompanding('N', N, 'M', M, 'num_symbols', num_symbols, 'mu', 255);
            
            % Simulação de BER
            ber_results = struct();
            ber_results.clipping = zeros(size(snr_db));
            ber_results.slm = zeros(size(snr_db));
            ber_results.pts = zeros(size(snr_db));
            ber_results.companding = zeros(size(snr_db));
            
            fprintf('Iniciando simulação de BER...\n');
            
            for snr_idx = 1:length(snr_db)
                fprintf('SNR = %d dB\n', snr_db(snr_idx));
                
                % Clipping Duro
                ber_results.clipping(snr_idx) = simulate_ber(clipping, snr_db(snr_idx));
                
                % SLM
                ber_results.slm(snr_idx) = simulate_ber_with_slm(slm, snr_db(snr_idx));
                
                % Companding
                ber_m = 0;
                for i = 1:10
                    [symbols, bits] = generate_data(companding);
                    tx_signal = ofdm_modulate(companding, symbols);
                    tx_comp = compress(companding, tx_signal);
                    
                    signal_power = mean(abs(tx_comp).^2);
                    noise_power = signal_power / (10^(snr_db(snr_idx)/10));
                    noise = sqrt(noise_power/2) * (randn(size(tx_comp)) + 1j*randn(size(tx_comp)));
                    rx_signal = tx_comp + noise;
                    
                    rx_expanded = expand(companding, rx_signal);
                    rx_symbols = ofdm_demodulate(companding, rx_expanded); % Método assume-se existente na superclasse
                    
                    if strcmp(companding.mod_type, 'QPSK')
                        rx_bits = pskdemod(rx_symbols, 4, pi/4, 'gray');
                    else
                        rx_bits = qamdemod(rx_symbols, 16, 'gray', 'OutputType', 'bit');
                    end
                    
                    errors = sum(bits ~= rx_bits);
                    ber_m = ber_m + errors / length(bits);
                end
                ber_results.companding(snr_idx) = ber_m / 10;
            end
            
            % Plotagem das curvas de BER
            figure('Position', [100, 100, 800, 600]);
            
            algorithms = fieldnames(ber_results);
            colors = {'b-', 'r--', 'g-.', 'm:'};
            markers = {'o', 's', '^', 'd'};
            
            for i = 1:length(algorithms)
                plot(snr_db, ber_results.(algorithms{i}), ...
                    [colors{i}, markers{i}], 'LineWidth', 2, 'MarkerSize', 8);
                hold on;
            end
            
            % BER Teórica QPSK
            ber_theory = 0.5 * erfc(sqrt(10.^(snr_db/10)));
            plot(snr_db, ber_theory, 'k-', 'LineWidth', 2);
            
            xlabel('SNR (dB)');
            ylabel('BER');
            title('Desempenho de BER de Vários Algoritmos de Redução de PAPR');
            legend([algorithms; 'QPSK Teórico'], 'Location', 'southwest');
            grid on;
            ylim([1e-5, 1]);
            
            % Análise de perda de SNR
            fprintf('\n=== Análise de Perda de SNR (BER=10^{-3}) ===\n');
            target_ber = 1e-3;
            
            for i = 1:length(algorithms)
                ber_data = ber_results.(algorithms{i});
                idx = find(ber_data <= target_ber, 1);
                
                if ~isempty(idx)
                    snr_at_target = snr_db(idx);
                    snr_theory = interp1(log10(ber_theory), snr_db, log10(target_ber));
                    snr_loss = snr_at_target - snr_theory;
                    
                    fprintf('%-10s: SNR@BER=1e-3 = %.2f dB, Perda de SNR = %.2f dB\n', ...
                        algorithms{i}, snr_at_target, snr_loss);
                end
            end
        end
    end
end

Referência do Código Original: www.youwenfan.com/contentcsu/55026.html

  1. Recomendações de Aplicação Prática

5.1 Guia de Seleção de Algoritmo

Cenário de Aplicação Algoritmo Recomendado Justificativa
Comunicação em Tempo Real Clipping, Companding Baixa complexidade, baixa latência
Alta Confiabilidade SLM, PTS Sem distorção, bom desempenho de BER
Dispositivos Móveis Companding, Clipping Baixo consumo de energia, implementação simples
Sistemas de Transmissão SLM Tolerância ao overhead de informação de banda lateral
Comunicações Militares PTS Boa segurança, desempenho superior

5.2 Sugestões de Otimização de Parâmetros


%% Função de Otimização de Parâmetros
function optimize_parameters()
    % Otimização de parâmetros
    
    % 1. Otimização do valor U para SLM
    N = 64;
    U_values = [2, 4, 8, 16, 32];
    papr_gain = zeros(size(U_values));
    complexity = zeros(size(U_values));
    
    for i = 1:length(U_values)
        slm = SLM('N', N, 'U', U_values(i));
        
        % Avaliação de desempenho
        papr_data = [];
        for j = 1:50
            [symbols, ~] = generate_data(slm);
            [tx_slm, ~] = apply_slm(slm, symbols);
            papr = calculate_papr(slm, tx_slm);
            papr_data = [papr_data, papr];
        end
        
        % PAPR Original
        tx_original = ofdm_modulate(slm, symbols);
        papr_orig = calculate_papr(slm, tx_original);
        
        papr_gain(i) = mean(papr_orig) - mean(papr_data);
        complexity(i) = U_values(i) * N;
    end
    
    % Busca pelo valor ótimo de U
    figure;
    yyaxis left;
    plot(U_values, papr_gain, 'b-o', 'LineWidth', 2);
    ylabel('Ganho de PAPR (dB)');
    
    yyaxis right;
    plot(U_values, complexity, 'r-s', 'LineWidth', 2);
    ylabel('Complexidade Computacional');
    
    xlabel('Valor de U');
    title('Otimização de Parâmetros SLM');
    legend('Ganho de PAPR', 'Complexidade Computacional');
    grid on;
    
    % 2. Otimização da Razão de Clipping
    CR_values = 0.5:0.1:1.0;
    papr_clipped = zeros(size(CR_values));
    ber_clipped = zeros(size(CR_values));
    
    for i = 1:length(CR_values)
        clipping = HardClipping('clip_ratio', CR_values(i));
        
        % Avaliação de PAPR
        papr_data = [];
        for j = 1:50
            [symbols, ~] = generate_data(clipping);
            tx_signal = ofdm_modulate(clipping, symbols);
            tx_clipped = apply_clipping(clipping, tx_signal);
            papr = calculate_papr(clipping, tx_clipped);
            papr_data = [papr_data, papr];
        end
        papr_clipped(i) = mean(papr_data);
        
        % Avaliação de BER
        ber_clipped(i) = simulate_ber(clipping, 10);  % SNR=10dB
    end
    
    figure;
    yyaxis left;
    plot(CR_values, papr_clipped, 'b-o', 'LineWidth', 2);
    ylabel('PAPR Médio (dB)');
    
    yyaxis right;
    semilogy(CR_values, ber_clipped, 'r-s', 'LineWidth', 2);
    ylabel('BER');
    
    xlabel('Razão de Clipping (CR)');
    title('Otimização de Parâmetros de Clipping');
    legend('PAPR', 'BER');
    grid on;
end
  1. Conclusão

6.1 Resumo do Desempenho dos Algoritmos

Algoritmo Ganho PAPR Impacto na BER Complexidade Computacional Informação de Banda Lateral Cenário de Aplicação
Clipping Duro 3-5 dB Severo Baixa Não Sistemas de tempo real de baixo custo
SLM 4-6 dB Nenhum Média Sim Transmissão, rádio fixo
PTS 5-7 dB Nenhum Alta Sim Rádio de alto desempenho
Companding 2-4 dB Leve Baixa Não Comunicações móveis

6.2 Código MATLAB de Uso Prático


% Exemplo de uso rápido
clear; clc; close all;

% 1. Criação do sistema OFDM
ofdm = OFDMSystem('N', 64, 'M', 4, 'mod_type', 'QPSK');

% 2. Geração de dados
[symbols, bits] = generate_data(ofdm);

% 3. Aplicação de SLM para reduzir PAPR
slm = SLM('N', 64, 'U', 4);
[tx_slm, idx] = apply_slm(slm, symbols);

% 4. Cálculo de PAPR
papr_original = calculate_papr(ofdm, ofdm_modulate(ofdm, symbols));
papr_slm = calculate_papr(slm, tx_slm);

fprintf('PAPR Original: %.2f dB\n', mean(papr_original));
fprintf('PAPR após SLM: %.2f dB\n', mean(papr_slm));
fprintf('Ganho de PAPR: %.2f dB\n', mean(papr_original) - mean(papr_slm));

% 5. Plotagem dos resultados
figure;
subplot(1,2,1);
histogram(papr_original, 20, 'FaceColor', 'b');
xlabel('PAPR (dB)'); ylabel('Frequência');
title('Distribuição PAPR OFDM Original');

subplot(1,2,2);
histogram(papr_slm, 20, 'FaceColor', 'r');
xlabel('PAPR (dB)'); ylabel('Frequência');
title('Distribuição PAPR após SLM');

Tags: OFDM PAPR SLM PTS Clipping

Publicado em 7-26 14:35