1 内容介绍

在本文中,我们为大规模多用户 (MU) 多输入多输出 (MIMO) 无线系统提出了一种新颖的数据检测算法和相应的 VLSI 设计。我们的算法使用基于交替方向乘法器 (ADMM) 的无限范数约束均衡,称为 ADMIN。ADMIN 是一种迭代算法,当基站 (BS) 和用户天线的数量之比较小时,它的性能大大优于线性检测器。在第一次迭代中,ADMIN 计算线性最小均方误差 (MMSE) 解,这在 BS 和用户天线数量之比较大时就足够了。我们为支持 16 和 32 用户系统的基于 LDL 分解的软输出 ADMIN 开发分时和迭代 VLSI 架构。我们提出了用于 28-nm CMOS 中的 16-64 个天线基站的专用集成电路 (ASIC) 设计,支持多达 64 个正交幅度调制 (QAM)。16 用户 ADMIN ASIC 达到 303 Mb/s,同时耗散 85 mW。

2 部分代码

% -----------------------------------------------------

% -- Simulation of state-of-the-art massive MIMO detection algorithms

% -- Author: Shahriar Shahabuddin

% -- Email: shahriar.cwc@gmail.com

% This simulator is based on Christoph Studer's simple MIMO simulator. This

% simulator contains the following algorithms:

% (1) Conventional detection schemes: matched filtering, MMSE, SIMO

% (2) Approximate Inversion Based Detection: neumann-series approximation,

% gauss-seidel detection, conjugate-gradient detection

% (3) BOX detection based methods: ADMIN, OCD

%

% Please cite the following paper if you use this simulator,

% S. Shahabddin, M. Juntti and C. Studer, "ADMM-based infinity-norm

% detector for large-scale MIMO", IEEE International symposium of circuits

% and systems, Maryland, USA, May 2017.

% -----------------------------------------------------

function massiveMIMOdetectors(varargin)

% -- set up default/custom parameters

close all

if isempty(varargin)

disp('using default simulation settings and parameters...')

% set default simulation parameters

par.suffix = 'exp'; % simulation name suffix: 'exp' experimental

par.runId = 0; % simulation ID (used to reproduce results)

par.MR = 64; % receive antennas

par.MT = 16; % user terminals (set not larger than MR!)

par.mod = '64QAM'; % modulation type: 'BPSK','QPSK','16QAM','64QAM'

par.simName = ['ERR_' num2str(par.MR) 'x' num2str(par.MT) '_' par.mod '_' par.suffix] ;  % simulation name (used for saving results)

par.trials = 100; % number of Monte-Carlo trials (transmissions)

par.SNRdB_list = 10:2:20; % list of SNR [dB] values to be simulated

par.detector = {'Conjugate-Gradient','Neumann','Gauss-Seidel','OCDBOX','ADMIN'}; % define detector(s) to be simulated

% algorithm specific

par.alg.maxiter = 3;

else

disp('use custom simulation settings and parameters...')

par = varargin{1}; % only argument is par structure

end

% -- initialization

% use runId random seed (enables reproducibility)

%   rng(par.runId);

% set up Gray-mapped constellation alphabet (according to IEEE 802.11)

switch (par.mod)

case 'BPSK'

par.symbols = [ -1 1 ];

case 'QPSK'

par.symbols = [ -1-1i,-1+1i, ...

+1-1i,+1+1i ];

case '16QAM'

par.symbols = [ -3-3i,-3-1i,-3+3i,-3+1i, ...

-1-3i,-1-1i,-1+3i,-1+1i, ...

+3-3i,+3-1i,+3+3i,+3+1i, ...

+1-3i,+1-1i,+1+3i,+1+1i ];

case '64QAM'

par.symbols = [ -7-7i,-7-5i,-7-1i,-7-3i,-7+7i,-7+5i,-7+1i,-7+3i, ...

-5-7i,-5-5i,-5-1i,-5-3i,-5+7i,-5+5i,-5+1i,-5+3i, ...

-1-7i,-1-5i,-1-1i,-1-3i,-1+7i,-1+5i,-1+1i,-1+3i, ...

-3-7i,-3-5i,-3-1i,-3-3i,-3+7i,-3+5i,-3+1i,-3+3i, ...

+7-7i,+7-5i,+7-1i,+7-3i,+7+7i,+7+5i,+7+1i,+7+3i, ...

+5-7i,+5-5i,+5-1i,+5-3i,+5+7i,+5+5i,+5+1i,+5+3i, ...

+1-7i,+1-5i,+1-1i,+1-3i,+1+7i,+1+5i,+1+1i,+1+3i, ...

+3-7i,+3-5i,+3-1i,+3-3i,+3+7i,+3+5i,+3+1i,+3+3i ];

end

% extract average symbol energy

par.Es = mean(abs(par.symbols).^2);

% precompute bit labels

par.Q = log2(length(par.symbols)); % number of bits per symbol

par.bits = de2bi(0:length(par.symbols)-1,par.Q,'left-msb');

% track simulation time

time_elapsed = 0;

% -- start simulation

% initialize result arrays (detector x SNR)

res.VER = zeros(length(par.detector),length(par.SNRdB_list)); % vector error rate

res.SER = zeros(length(par.detector),length(par.SNRdB_list)); % symbol error rate

res.BER = zeros(length(par.detector),length(par.SNRdB_list)); % bit error rate

% generate random bit stream (antenna x bit x trial)

bits = randi([0 1],par.MT,par.Q,par.trials);

% trials loop

tic

for t=1:par.trials

% generate transmit symbol

idx = bi2de(bits(:,:,t),'left-msb')+1;

s = par.symbols(idx).';

% generate iid Gaussian channel matrix & noise vector

n = sqrt(0.5)*(randn(par.MR,1)+1i*randn(par.MR,1));

H = sqrt(0.5)*(randn(par.MR,par.MT)+1i*randn(par.MR,par.MT));

% transmit over noiseless channel (will be used later)

x = H*s;

% SNR loop

for k=1:length(par.SNRdB_list)

% Current SNR point in dBs

SNR_dB = par.SNRdB_list(k);

% Linear SNR

SNR_lin = 10.^(SNR_dB./10);

% Variance of complex noise per receive antenna

N0 = par.Es*par.MT/SNR_lin;

% transmit data over noisy channel

y = x+sqrt(N0)*n;

% algorithm loop

for d=1:length(par.detector)

switch (par.detector{d}) % select algorithms

case 'MF' % Matched Filter

[idxhat,bithat] = MF(par,H,y,N0);

case 'MMSE' % MMSE detector

[idxhat,bithat] = MMSE(par,H,y,N0);

case 'SIMO' % SIMO lower bound

[idxhat,bithat] = SIMO(par,H,y,N0,s);

case 'ADMIN' % ADMM-based Infinity Norm detector

[idxhat,bithat] = ADMIN(par,H,y,N0);

case 'OCDBOX' % co-ordinate descent (optimized) detector

[idxhat,bithat] = OCDBOX(par,H,y);

case 'Neumann' % coordinate descent

[idxhat,bithat] = Neumann(par,H,y,N0);

case 'Gauss-Seidel' % Gauss-Seidel detector

[idxhat,bithat] = Gauss_Seidel(par,H,y,N0);

case 'Conjugate-Gradient' % conjugate gradient detector

[idxhat,bithat] = CG(par,H,y,N0);

otherwise

error('par.detector type not defined.')

end

% -- compute error metrics

err = (idx~=idxhat);

res.VER(d,k) = res.VER(d,k) + any(err);

res.SER(d,k) = res.SER(d,k) + sum(err)/par.MT;

res.BER(d,k) = res.BER(d,k) + sum(sum(bits(:,:,t)~=bithat))/(par.MT*par.Q);

end % algorithm loop

end % SNR loop

% keep track of simulation time

if toc>10

time=toc;

time_elapsed = time_elapsed + time;

fprintf('estimated remaining simulation time: %3.0f min.\n',time_elapsed*(par.trials/t-1)/60);

tic

end

end % trials loop

% normalize results

res.VER = res.VER/par.trials;

res.SER = res.SER/par.trials;

res.BER = res.BER/par.trials;

res.time_elapsed = time_elapsed;

% -- save final results (par and res structure)

%   save([ par.simName '_' num2str(par.runId) ],'par','res');

% -- show results (generates fairly nice Matlab plot)

marker_style = {'bo-','rs--','mv-.','kp:','g*-','c>--','yx:'};

figure(1)

for d=1:length(par.detector)

if d==1

semilogy(par.SNRdB_list,res.BER(d,:),marker_style{d},'LineWidth',2)

hold on

else

semilogy(par.SNRdB_list,res.BER(d,:),marker_style{d},'LineWidth',2)

end

end

hold off

grid on

xlabel('average SNR per receive antenna [dB]','FontSize',12)

ylabel('bit error rate (BER)','FontSize',12)

axis([min(par.SNRdB_list) max(par.SNRdB_list) 1e-4 1])

legend(par.detector,'FontSize',12)

set(gca,'FontSize',12)

end

% -- set of detector functions

%% Matched filter

function [idxhat,bithat] = MF(par,H,y)

xhat = H' * y / norm(H(:));

[~,idxhat] = min(abs(xhat*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

%% MMSE detector (MMSE)

function [idxhat,bithat] = MMSE(par,H,y,N0)

xhat = (H'*H+(N0/par.Es)*eye(par.MT))\(H'*y);

[~,idxhat] = min(abs(xhat*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

%% SIMO bound

function [idxhat,bithat] = SIMO(par,H,y,s)

z = y-H*s;

xhat = zeros(par.MT,1);

for m=1:par.MT

hm = H(:,m);

yhat = z+hm*s(m,1);

xhat(m,1) = hm'*yhat/norm(hm,2)^2;

end

[~,idxhat] = min(abs(xhat*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

%% Neumann-Series Approximation based massive MIMO detection

function [idxhat,bithat] = Neumann(par,H,y,N0)

A = H'*H+(N0/par.Es)*eye(par.MT);

MF = H'*y;

D = diag(diag(A));

E = triu(A,1)+tril(A,-1);

Ainv = 0;

for i = 0:par.alg.maxiter

Ainv = Ainv+((-inv(D)*E)^i)*inv(D);

end

xhat = Ainv*MF;

[~,idxhat] = min(abs(xhat*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

%% Gauss-Seidel massive MIMO detection

function [idxhat,bithat] = Gauss_Seidel(par,H,y,N0)

A = H'*H+(N0/par.Es)*eye(par.MT);

MF = H'*y;

D = diag(diag(A));

E = -triu(A,1);

F = -tril(A,-1);

xhat = diag(inv(D));% inv(D)*MF;  %%% Check Gauss Seidel detection paper

for i = 0:par.alg.maxiter

xhat = inv(D-E)*(F*xhat+MF);

end

[~,idxhat] = min(abs(xhat*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

%% Conjugate Gradient massive MIMO detection

function [idxhat,bithat] = CG(par,H,y,N0)

A = H'*H+(N0/par.Es)*eye(par.MT);

MF = H'*y;

r = MF;

p = r;

v = zeros(par.MT,1);

for k = 1:par.alg.maxiter

e = A*p;

alpha  = norm(r)^2/(p'*e);

v = v+alpha*p;

new_r = r-alpha*e;

beta = norm(new_r)^2/norm(r)^2;

p = new_r+beta*p;

r = new_r;

end

xhat = v;

[~,idxhat] = min(abs(xhat*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

%% ADMM-based infinity norm (ADMIN) detector

function [idxhat,bithat] = ADMIN(par,H,y,N0)

% -- preprocessing

% by setting beta to N0/par.Es we get the MMSE estimator in the first iteration

% this is pretty neat as this is a very good detector already

beta = N0/par.Es;%*3; % tweaking this one by 3 improved performance significantly

A = H'*H + beta*eye(par.MT);

L = chol(A,'lower');

yMF = H'*y;

% -- initialization

gamma = (1+sqrt(5))/2;%*2; %% tweaked with 2 to improve performance

alpha = max(real(par.symbols)); % symbol box

zhat = zeros(par.MT,1);

lambda = zeros(par.MT,1);

% -- ADMM loop

for iter=1:par.alg.maxiter

xhat = (L')\(L\(yMF+beta*(zhat-lambda))); % step 1

zhat = projinf(par,xhat+lambda,alpha); % step 2

lambda = lambda-real(gamma*(zhat-xhat)); % step 3

lambda = real(lambda);

end

% -- hard output detection

[~,idxhat] = min(abs(zhat*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

%% Optimized Coordinate Descent (OCD) BOX version

function [idxhat,bithat] = OCDBOX(par,H,y)

% -- initialization

[row, col] = size(H);

alpha = 0; % no regularization for BOX detector

beta = max(real(par.symbols));

% -- preprocessing

dinv = zeros(col,1);

p = zeros(col,1);

for uu=1:col

normH2 = norm(H(:,uu),2)^2;

dinv(uu,1) = 1/(normH2+alpha);

p(uu,1) = dinv(uu)*normH2;

end

r = y;

zold = zeros(col,1);

znew = zeros(col,1);

deltaz = zeros(col,1);

% -- OCD loop

for iters=1:par.alg.maxiter

for uu=1:col

tmp = dinv(uu)*(H(:,uu)'*r)+p(uu)*zold(uu);

znew(uu) = projinf(par,tmp,beta);

deltaz(uu) = znew(uu)-zold(uu);

r = r - H(:,uu)*deltaz(uu);

zold(uu) = znew(uu);

end

end

[~,idxhat] = min(abs(znew*ones(1,length(par.symbols))-ones(par.MT,1)*par.symbols).^2,[],2);

bithat = par.bits(idxhat,:);

end

% project onto alpha infinity-tilde-norm ball

function sproj = projinf(par,s,alpha)

switch par.mod

case 'BPSK'

v = real(s);

sproj = min(abs(v),alpha).*v;

otherwise

sr = real(s);

idxr = abs(sr)>alpha;

sr(idxr) = sign(sr(idxr))*alpha;

si = imag(s);

idxi = abs(si)>alpha;

si(idxi) = sign(si(idxi))*alpha;

sproj = sr +1i*si;

end

end

3 运行结果

4 参考文献

[1] Shahabuddin S ,  Hautala I ,  Juntti M , et al. ADMM-Based Infinity-Norm Detection for Massive MIMO: Algorithm and VLSI Architecture[J]. IEEE Transactions on Very Large Scale Integration (VLSI) Systems, 2021, PP(99):1-13.

博主简介:擅长智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机、雷达通信、无线传感器等多种领域的Matlab仿真,相关matlab代码问题可私信交流。

部分理论引用网络文献,若有侵权联系博主删除。

【通信】基于 ADMM 的大规模 MIMO 无穷范数检测附matlab代码相关推荐

  1. 开源代码分享(10)—基于ADMM算法的电动汽车群体充电优化(附matlab代码)

    1.引言 电动汽车是汽车行业中快速增长的市场.此外,广泛使用可再生能源来驱动电动汽车使其具备可持续性,并且温室气体排放极低.因此,服务提供商正在转向使用电动车队推广环境可持续性.然而,与传统车辆不同, ...

  2. 【图像检测】基于 AlexNet 和 SVM 实现异常螺母检测附matlab代码

    1 内容介绍 考虑到异常检测问题中正负样本严重失衡,难以满足卷积神经网络训练对样本的要求,提出了基于AlexNet模型的异常检测模型.在数据预处理阶段,通过隔帧采样的方式生成3组训练数据,并利用预训练 ...

  3. 【信号检测】基于LSTM实现工业机器信号数据异常检测附matlab代码

    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信.

  4. 【故障诊断】基于贝叶斯优化支持向量机的轴承故障诊断附matlab代码

    1 内容介绍 贝叶斯网络(Bayesian Network或BN)是人工智能领域进行建模和不确定性推理的一个有效工具.贝叶斯网推理的基本任务是:给定一组证据变量观察值,通过搜索条件概率表计算一组查询变 ...

  5. 【角点检测】 基于各向异性高斯方向导数滤波器实现图像角点检测附matlab代码

    1 内容介绍 为了改进噪声鲁棒性和定位准确性,利用各向异性高斯方向导数滤波器,提出多方向角点检测算法.该算法利用一组各向异性高斯方向导数滤波器对输入图像进行卷积处理得到各个方向的滤波器响应.对于每个像 ...

  6. 【图像检测】基于Itti模型实现图像显著性检测附matlab代码

    1 简介 视觉显著性计算模型以心理学.神经科学.认知理论等领域的研究成果或假说为前提,建立数学模型来模拟人类视觉系统指引注意力分配和视觉认知的过程,通过模拟和仿真人类视觉感知机理,将存在待检测目标的人 ...

  7. 【车间调度】基于改进帝国企鹅算法求解车间调度问题附matlab代码

    1 内容介绍 传统车间调度问题仅仅考虑工件的分配问题.而柔性车间调度问题在传统车间调度问题上做了一定的延伸,它更接近实际生产过程的原因是由于其在传统车间调度问题中加入了对加工机器的选择.因此对其的研究 ...

  8. 【智能优化算法-鲸鱼算法】基于鲸鱼算法求解多目标优化问题附matlab代码(NSWOA)

    1 内容介绍 为了解决多目标优化的相关问题,鲸鱼优化算法结合多目标相关理论,并在算法中加入了非排序思路,提出了一种求解多目标问题的鲸鱼优化算法.​ 2 仿真代码 %% Non Sorted Whale ...

  9. 【图像分割】基于计算机视觉实现胸部CT肺质提取附matlab代码

    1 内容介绍 在现代医学领域中,医学影像处理技术随着计算机科学和影像技术的进步,已经成为医学领域重要的一个分支.室外光照度不均.CT自身空间分辨率和层厚参数.人体组织器官蠕动等诸多外界因素造成了医学X ...

最新文章

  1. 实战:基于深度学习的道路损坏检测
  2. 自已编写C# DLL 绑定到unity进程进行单步调试
  3. Linux内核分析— —计算机是如何工作的(20135213林涵锦)
  4. (十一)MyBatis的动态SQL:trim元素
  5. 第七章|7.3并发编程|协程
  6. 正态分布的前世今生(3)
  7. Linux环境变量详解
  8. HDOJ水题集合8:DBFS
  9. linux内存管理_Linux内存管理(转)
  10. 孙鑫VC学习笔记:第十二讲 (六) 读写注册表
  11. MYSQL中删除重复记录的方法
  12. centos中多台主机免密登录_关于单点登录(SSO)数据共享(session和redis)的那点事?...
  13. Java网络编程socket实现(demo)
  14. QT线程创建的两种方法
  15. 将淘宝客数据导入自己的数据库
  16. 学游戏设计好就业吗?有“钱”途吗?
  17. Codewars-Java编程刷题学习4-Jaden Casing Strings
  18. 邮箱附件钓鱼常用技法
  19. 黑猫带你学UFS协议第1篇:全网最全UFS协议中文详讲,这份学习框架图,你值得拥有!!!(持续更新中...)
  20. MATLAB打开后一直在初始化,或者初始化很慢问题

热门文章

  1. Java计算机毕业设计 物业管理系统
  2. 许三多:浮躁社会的反义词
  3. 小学计算机程序竞赛,25届宁波市中小学计算机程序设计竞赛初赛试题
  4. 按键精灵361插件后台脚本
  5. Vulkan Tutorial 4
  6. USB Type C数据线接线方式、工作原理
  7. 微信API接口、微信二次开发API调用
  8. Flutter urlencode转换
  9. 台大机器学习基石学习笔记
  10. JAVA 开发相关软件介绍以及安装使用教程(初学者一定要收藏)