【MIMO】Massive MIMOチャネルの角度領域における局所性を確認するシミュレータ

# 0. はじめに
**Massive MIMO(mMIMO)は、移動体無線通信システムにおける周波数利用効率や電力効率の向上、セルに収容可能なユーザ数の増加などが期待される技術である。**
mMIMOによってセルに収容される複数ユーザの通信品質を高めるため、ユーザ間の信号干渉を補償する技術（干渉補償技術）として、LSやMMSEを用いたものからDeep Learningを用いたものまで様々提案されている[1]。
干渉補償技術は、基地局で利用されるmMIMOとユーザの間に構築される電波伝搬 (mMIMO Channel)の推定値を入力とする。**mMIMO Channelの特性を利用した干渉補償技術を開発することで、通信品質の劣化を抑えながらの計算コスト低減が期待される。**
**本稿では、文献[1]で指摘されるmMIMO Channelの角度領域における局所性をパラメータを変えながら確認できるシミュレータ**を紹介する。

# 1. システムと伝搬モデル
システムと伝搬モデルを紹介する。

## 1.1 システム
下記は、文献[1]のFig.1を抜粋したものである。
Fig.1の左は、基地局のmMIMOであり、半波長の等間隔でN個のアンテナ素子が並べられたULA(Uniform Linear Array)アンテナが利用される。
Fig.1の中央は、シングルアンテナのユーザ端末がK個配置される様子を表す。
**Fig.1の右は、ユーザ毎のmMIMO Channelをフーリエ変換によって角度領域に変換したもので、特定箇所の色が濃くなっている。これは、mMIMO Channelの角度領域において局所性があることを表現している。本稿で紹介するシミュレータは、この局所性をグラフで表示するもので、様々なパラメータ（e.g. アンテナ素子数）と局所性の関係を確認することに役立つ。**

![Screenshot from 2023-02-08 22-29-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756450/9b1f5bba-46f4-e1bf-757f-0ac305269e90.png)

## 1.2 伝搬モデル
mMIMO Channelモデルは、文献[1]のp.5に示されるモデルを利用した。
詳細は文献[1]を確認いただきたい。

# 2. シミュレータの実行
本稿にて紹介するシミュレータは、**mMIMO Channelの角度領域における局所性をパラメータを変えながら確認できるもの**である。
シミュレータの実行方法とそのグラフ表示を示す。尚、シミュレータのプログラムは後に示す。

## 2.1 シミュレータの実行例とパラメータの説明
シミュレータの実行例を以下に示す。
```
# python3 main.py 32 3 2 10 20.0 3 123  0
```
各パラメータの説明は以下である。ULAのアンテナ素子数や、ユーザの数、マルチパスの条件などが指定できる。
#1 : the number of antennas in ULA array of BS
#2 : the number of users in a cell
#3 : the number of propagation path a user
#4 : > 0, the power degradation of a reflected path [dB]
#5 : the variance of angle in multi-path fading [deg]
#6 : flag of random {1,2,3,other} = {angle, amp, amp & angle}
#7 : seed of random generator
#8 : DEBUG flag {0,1} = {off, on}

## 2.2 シミュレータの実行結果
2.1に示したコマンドでシミュレータを実行すると、以下のグラフが表示され、ユーザ数の3に対応する数のピークが確認できた。尚、内部で乱数を利用しているため、読書側で実行する際には、異なる結果になると見込まれる。
シミュレータの利用によって、パラメータとmMIMO Channelの角度領域における局所性の関係を直感的に把握できる。

![Screenshot from 2023-02-05 13-30-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756450/f9176092-1a97-282a-0f27-55aef0ac8b6c.png)


# 3. シミュレータのプログラム
シミュレータのプログラムを紹介する。

## 3.1 ファイル構成
ファイル構成を以下に示す。
main.pyはトップの実行プログラムである。
ch.pyとfft.pyとgraph.pyはサブのプログラムである。

├── ch.py
├── fft.py
├── graph.py
├── main.py

## 3.2 各ファイルの説明
### 3.2.1 ch.py
mMIMO Channelモデルを構築するプログラムである。
```ch.py
import numpy as np

class UserChannel:

        def __init__(self,Nant,Npath,VarAngle,FdB,FLAG):
                self.Nant = Nant
                self.Npath= Npath
                self.VarAngle = float(VarAngle/180.0)
                self.FdB  = FdB
                self.Amp  = np.ones(self.Npath,dtype=complex)
                self.AoA  = np.ones(self.Npath,dtype=float)
                if FLAG == 3:
                        self.set_angle()
                        self.set_amp()
                elif FLAG == 2:
                        self.set_amp()
                elif FLAG == 1:
                        self.set_angle()
                self.create()

        def set_angle(self):
                mean = np.random.rand(self.Npath)
                self.AoA = mean + np.random.uniform(low=-self.VarAngle,high=self.VarAngle,size=self.Npath)

        def set_amp(self):
                self.Amp = np.exp(-2.j*np.pi*np.random.rand(self.Npath))
                for i in range(self.Npath):
                        self.Amp[i] = self.Amp[i] * (10.0 ** (-self.FdB * float(i)/10.0) )

        def create(self):
                A = np.array([i for i in range(self.Nant)],dtype=float)
                B = np.zeros([self.Nant,self.Npath],dtype=float)
                for i0 in range(self.Nant):
                        for i1 in range(self.Npath):
                                B[i0][i1] = A[i0] * self.AoA[i1]

                self.Mat = self.Amp * np.exp(-1j * np.pi * B)

                self.Vec = np.zeros(self.Nant,dtype=complex)
                for i0 in range(self.Nant):
                        for i1 in range(self.Npath):
                                self.Vec[i0] += self.Mat[i0][i1]

        def get_mat(self):
                return self.Mat

        def get_vec(self):
                return self.Vec

        def __call__(self):
                print(self.Mat)
```
### 3.2.2 fft.py
フーリエ変換用のプログラムである。
```fft.py
import numpy as np

class fft:
        def __init__(self,N):
                self.N = N
                self.gen()

        def gen(self):
                A = [ 1.*i for i in range(self.N)]
                B = [ (-self.N+1.0+2.*i)/float(self.N) for i in range(self.N)]
                C = np.zeros([self.N,self.N],dtype=float)
                for i0 in range(self.N):
                        for i1 in range(self.N):
                                C[i0][i1] = A[i0] * B[i1]
                self.W = 1./np.sqrt(self.N) * np.exp(-1.j * np.pi * C)

        def __call__(self):
                print("-- FFT Weights --")
                print(np.round(self.W,decimals=3))
                print("-- W * W.H --")
                print(np.round(np.dot(self.W,np.conjugate(self.W.T)),decimals=3))

        def transf(self,IN):
                return np.dot(self.W,IN)

        def inv_transf(self,IN):
                return np.dot(np.conjugate(self.W.T),IN)
```
### 3.2.3 graph.py
mMIMO Channelの角度領域における分布をグラフ表示するプログラムである。
```graph.py
import matplotlib.pyplot as plt
import numpy as np

def pltgraph(Nant,Nuser,DATA):
        x = [i for i in range(Nant)]
        PW = DATA * np.conjugate(DATA)
        for i in range(Nuser):
                plt.bar(x,PW[i])
        plt.xlabel("Samples in Fourier domain")
        plt.ylabel("Power Gain")
        plt.xlim(0,Nant-1)
        plt.show()
```
### 3.2.4 main.py
実行用のプログラムである。
```main.py
import sys
import numpy as np

from ch import UserChannel
from fft import fft
from graph import pltgraph

def main(Nant,Nuser,Npath,VarAng,FdB,FLAG,DEBUG):
        f0 = fft(Nant)
        users = []
        FTMatrix = []
        for i in range(Nuser):
                users.append(UserChannel(Nant,Npath,VarAng,FdB,FLAG))
                IN = users[i].get_vec()
                if DEBUG == 1:
                        print("--matrix of multi path between",i,"-th user and a BS")
                        print(np.round(users[i].get_mat(),decimals=4))
                FTMatrix.append(f0.transf(IN))
        print("-- power distribution of the user channels in Fourier domain --")
        for i in range(Nuser):
                print(np.round(FTMatrix[i]*np.conjugate(FTMatrix[i]),decimals=3).real)
        print("-- phase distribution of the user channels in Fourier domain --")
        for i in range(Nuser):
                print(np.round(np.angle(FTMatrix[i]),decimals=3))
        pltgraph(Nant,Nuser,FTMatrix)

if __name__ == '__main__':
        np.set_printoptions(suppress=True)
        args = sys.argv
        if len(args) == 9:
                Nant  = int(args[1])
                Nuser = int(args[2])
                Npath = int(args[3])
                FdB   = int(args[4])
                VarAng = float(args[5])
                FLAG  = int(args[6])
                seed  = int(args[7])
                DEBUG = int(args[8])
                np.random.seed(seed)
        else:
                print("Set  Arguments as int")
                print("#1 : the number of antennas in ULA array of BS")
                print("#2 : the number of users in a cell ")
                print("#3 : the number of propagation path a user")
                print("#4 : > 0, the power degradation of a reflected path [dB]")
                print("#5 : the variance of angle in multi-path fading [deg]")
                print("#6 : flag of random {1,2,3,other} = {angle, amp, amp & angle}")
                print("#7 : seed of random generator")
                print("#8 : DEBUG flag {0,1} = {off, on}")
                print("example :  python3 main.py 32 3 2 30 10.0 3 15 0")
                sys.exit(0)

        main(Nant,Nuser,Npath,VarAng,FdB,FLAG,DEBUG)
```
# 4. 考察
シミュレータの利用によって、5番目のパラメータであるマルチパスの角度の分散を小さくするほど、mMIMO Channelの角度領域における局所性が強くなる傾向を確認できた。文献[1]では、このマルチパスの角度の分散が小さいという仮定を置いており、局所性が現れるキー・パラメータといえる。
また、4番目のパラメータであるマルチパスの電力強度の低下を著しくするほど、mMIMO Channelの角度領域における局所性が強くなる傾向を確認できた。これは、受信電力の軸でマルチパスの影響が小さくなり、相対的に主波の影響が強くなるためである。ビーム幅が狭いアンテナを端末側や基地局側で利用する場合は、マルチパスの電力強度の低下は顕著になると考えられる。
実際の伝搬環境にて、これらのマルチパスの影響が小さくなる仮定が成り立てば、mMIMO Channelの角度領域における局所性が強くなると見込まれる。

# 5. まとめ
本稿では、**文献[1]で紹介されるmMIMO Channelの角度領域における局所性を確認できるシミュレータ**を紹介した。シミュレータは、ULAアンテナのアンテナ素子数やユーザの数、マルチパスの状況をパラメータとしており、上記の局所性を様々な条件で確認する際に役立つ。

# 文献
[1] https://arxiv.org/pdf/2108.09430.pdf