I expanded the 2×2 V-BLAST zero-forcing scheme to a general MxM scheme. For a general MxM matrix, the inverse cannot be precalculated by hand as I did for the 1×1 and 2×2 scheme. The inversion of a possibly large channel matrix can quickly get a very complex problem which needs a lot of computation power, especially if it is recalculated frequently, for example each micro second when assuming a coherence time of 1μs and therefore a CSI update rate of 1MHz.
To avoid the decoder getting a performance bottleneck, we need an efficient algorithm to calculate the inverse. I chose to use a LU decomposition. The matrix A is decomposed as A = PLU where L is unit-lower-triangular, U is upper-triangular, and P is a permutation matrix. To speed up the algorithm even more, I decided to use partial pivoting instead of complete pivoting which is payed with a little bit of accuracy loss.
I am using the linear algebra template library Eigen. It offers a set of linear decompositions, including the Eigen::PartialPivLU algorithm. With this given algorithm, the implementation of the MxM case is as easy as:
- Map the 2-dimensional CSI std::vector to a Eigen::MatrixXcf. ‘X’ stands for mutable dimension and ‘cf’ stands for the data type complex<float>.
- Invert the matrix with the decomposition Eigen::Partial::PivLU.
- Map the Eigen::MatrixXcf back to the 2-dimensional equalization std::vector.
- Equalize the input data by multiplying the input vector with the equalization matrix (= 2-dim std::vector) and converting the resulting vector into a serial stream.
About the usage of Eigen as a dependency for GNU Radio
In order to use Eigen3, you just need to include a directory with Eigen header files to the program or install them via your package management system.
Despite that, I don’t want to introduce any new dependencies to GNU Radio that are required to basically run it. This is the reason why I implement the decoder for the 1×1 and 2×2 MIMO scheme by hand. The general MxM implementation with Eigen is therefore just an optional feature for everyone who has installed Eigen.
I am checking for the existence of Eigen in the CMake process of the gr-digital module with
and thereafter enabling or disabling the ability of the decoder to handle MxM MIMO schemes with M>2. This is done by preprocessor directives which enable the general MxM case if the Eigen3 package is found. If not, the Eigen specific code is replaced with a std::runtime_error stating that Eigen3 has to be installed to enable the general MxM VBLAST decoder.
After doing some minor changes and writing the respective documentation for the in-tree top-level documentation of doxygen, I am finished with the implementation of the V-BLAST scheme. After that, I am going to start the third part of my project: Implementing a MIMO-OFDM transceiver which works over the air.
I am going to present you my detailed plan of how I want to approach this big task in my next blog post in one week.