## 2 Materials and Methods
### Development of the C++ Application and ArrayFire Optimization Techniques  
ArrayFire provides a complete API that solves the most common functionalities implemented with MATLAB language. Therefore, it can be considered that porting MATLAB to C++ using ArrayFire API is relatively straightforward, and some parts of the code are even equivalent line by line. Nevertheless, ArrayFire does not include some powerful functions available in MATLAB. For example, the function \"griddata\" allows different types of interpolations using uniform and not-uniform input data distribution. This function in MATLAB has some parts of the internal code visible to the user, but other parts are not available, making it impossible to reproduce its calculations. While ArrayFire version 3.8.0 includes a function for interpolation, it expects that input data will be uniformly organized. To solve this problem, we chose the open-source library ALGLIB, which provides a set of functions for 2D interpolation that can be used to circumvent the problem. The translation from MATLAB to C++ followed the rule of performing precisely the same calculations in the different algorithm steps. Nonetheless, due to the use of functions such as griddata, which does not have a straightforward translation, the results are not precisely the same. Once the conversion is completed, the code is optimized to improve execution time, maximizing parallelism and code execution in the GPU. The techniques applied are explained in the following paragraphs. (a) Vectorization  
The main technique to improve the execution time is the use of vectors. The objective is to execute the same operations in the different elements in a matrix. Of course, dependency between elements must not exist for vectorization to be a viable solution. One example of the application of this technique is the implementation using ArrayFire arrays of the following piece of code (see function projection_bolo) extracted from the \"original\" MATLAB code. In this case, pix(i,j,k) is the Projection matrix elements, which describes the geometrical contribution of each measurement to a certain pixel in the image. Rec1 is the reconstruction at the current iteration. The final result Prj represents the backprojection. In MATLAB this is implemented using loops and an if statement. The exact equivalent code implemented in C++, with the help of ArrayFire, is presented below (see af::array method projection_bolo). The first step is to obtain the portion of \"ppix\" with the relevant data to be processed, \"ppixSlices\". Then, the \"rec1\" 2D matrix is converted to a 3D matrix (repeating the data in the third dimension), using the function tile. Next, the two 3D matrices, \"ppixSlices\" and \"rec1 Slices\" are multiplied, which is the equivalent of the \"pix(i,j,k)*rec1(i,j)\" operation, for all the iterations, in the MATLAB code. The resulting 3D array is summed using ArrayFire's function af::sum. This operation \begin{table}
\begin{tabular}{c c c} \hline \hline
**Function** & **Time (ms)** & **Time for 15 Iterations** \\ \hline Initialization for smoothing on the open & 3183.0 & n/a \\ magnetic curves & 3.0 & n/a \\ Load projections & 165.0 & n/a \\ Backprojections & 10.0 & n/a \\ Uncertainty preparations & 20.0 & n/a \\ Projection lines approach loop & 2560.0 & 38,400.0 \\ Smooth the closed and open surfaces & 160.0 & 2400.0 \\ Smooth LCF inside and outside & 326.8 & 4902.0 \\ Evaluation of emissivity & 1.8 & 27.0 \\ Uncertainty estimation & 1363.5 & 5454.0 \\ Evaluation of the reconstruction projection & 42.0 & 630.0 \\ at iteration i\({}^{\text{th}}\) & 1.2 & n/a \\ Final projections & 1.2 & n/a \\ Compute profile radiation and noise & 7624.0 & n/a \\ \hline TOTAL & 15,460.3 & 62,819.2 \\ \hline \hline \end{tabular}
\end{table} 
Table 1: Execution times (in ms) obtained with the MATLAB profiler. results in a 1D matrix which needs to have the dimensions rearranged, to match the results from the original MATLAB code.