/** 
* @mainpage gpuNUFFT 
*
* gpuNUFFT - GPU Regridding of Radial 3-D MRI data
*
* - Andreas Schwarzl - andreas.schwarzl@student.tugraz.at
* - Florian Knoll - florian.knoll@nyumc.org
*
* @section INFO
*
*  GPU 3D regridding library with MATLAB(R) Mexfile output.
*  Go to subfolder CUDA to compile mexfiles. 
*
* @section REQUIREMENTS
*
* - CUDA
* - CMAKE 2.8
* - MATLAB 2008 or higher
* - Google test framework (optional)
*
*  CMAKE Options:
*  
*  - GEN_ATOMIC        : DEFAULT ON, enables fast library using atomic operations
*  - WITH_DEBUG        : DEFAULT OFF, enables Command-Line DEBUG output
*  - WITH_MATLAB_DEBUG : DEFAULT OFF, enables MATLAB Console DEBUG output
*  - GEN_TESTS         : DEFAULT OFF, generate Unit tests
*  
*  Prior to compilation, the path where MATLAB is installed has to be defined in the top level CMakeLists.txt file, e.g.:
*  
*  \code
*  SET(MATLAB_ROOT_DIR "/home/florian/Programs/MATLAB/R2012b" CACHE STRING "MATLAB Installation Directory")
*  \endcode
*  
*  Alternatively, it can be passed as command line argument when calling cmake, e.g.:
*
*  \code
*  cmake .. -DMATLAB_ROOT_DIR=/path/to/matlab
*  \endcode
*
*  
*  @section LINUX 
*
*  build project via cmake, starting from project root directory:
*  \code
*    > mkdir build
*    > cd build
*    > cmake ..
*    > make
*  \endcode
*	
* Note: This version of gpuNUFFT was tested with CUDA 5.0. NVIDIAs nvcc compiler did not support gcc 4.7 or higher at this time. It is therefore suggested to compile gpuNUFFT with gcc 4.6. One comfortable way to toggle between gcc/g++ versions is to use the update-alternatives tool.
*
* @section WINDOWS 
* 
* build project using cmake or cmake-gui, starting from project root directory:
*
*  \code
*    > mkdir build 
*    > cd build
*    > cmake .. -G "Visual Studio 2008 Win64" 
*    > Build created Solution gpuNUFFT.sln using Visual Studio
*  \endcode
*
*  Ensure that at least a Visual Studio 2008 Express build environment is setup correctly.
*  If the library shall run using Win64 check that all necessary Visual Studio Add-ons are
*  installed correctly and a Win64 dummy project can be created using VS.
*
* @section Run
*
*  The compiled CUDA-mexfiles will appear in the bin directory and are also copied 
*  automatically into the <b>gpuNUFFT/\@gpuNUFFT/private</b> directory . Include the gpuNUFFT
*  directory into the matlab search path, in order to run the provided demo example.
*
* @section Demo 
*
* Find a MATLAB demo reconstruction in the <b>matlab/demo</b> directory. 
* 
* Simple cpp examples (Google Test Unit tests) can be found in the <b>test</b> directory.  
*
* In a nutshell, one simple example from the unit tests: 
* 
* \code
  TEST(TestForwardBackward,Test64)
  {
    int kernel_width = 3;
    float osf = 1.25;//oversampling ratio
    int sector_width = 8;
    
    //Data
    int data_entries = 2;
    DType2* data = (DType2*) calloc(data_entries,sizeof(DType2)); //2* re + im
    data[0].x = 5;//Re
    data[0].y = 0;//Im
    data[1].x = 1;//Re
    data[1].y = 0;//Im

    //Coords
    //Scaled between -0.5 and 0.5
    //in triplets (x,y,z) as structure of array
    //p0 = (0,0,0)
    //p1 0 (0.25,0.25,0.25)
    DType* coords = (DType*) calloc(3*data_entries,sizeof(DType));//3* x,y,z
    coords[0] = 0.00; //x0
    coords[1] = 0.25; //x1
    
    coords[2] = 0.00; //y0
    coords[3] = 0.25; //y0
    
    coords[4] = 0.00; //z0
    coords[5] = 0.25; //z1

    //Input data array, complex values
    gpuNUFFT::Array<DType2> dataArray;
    dataArray.data = data;
    dataArray.dim.length = data_entries;
    
    //Input array containing trajectory in k-space
    gpuNUFFT::Array<DType> kSpaceData;
    kSpaceData.data = coords;
    kSpaceData.dim.length = data_entries;

    gpuNUFFT::Dimensions imgDims;
    imgDims.width = 64;
    imgDims.height = 64;
    imgDims.depth = 64;

    //precomputation performed by factory
    gpuNUFFT::GpuNUFFTOperatorFactory factory; 
    gpuNUFFT::GpuNUFFTOperator *gpuNUFFTOp = factory.createGpuNUFFTOperator(kSpaceData,kernel_width,sector_width,osf,imgDims);

    //Output Array
    gpuNUFFT::Array<CufftType> imgArray;
    
    //Perform FT^H Operation
    imgArray = gpuNUFFTOp->performGpuNUFFTAdj(dataArray);
    
    //Output Image
    CufftType* gdata = imgArray.data;
    
    //Perform FT Operation
    gpuNUFFT::Array<CufftType> kSpace = gpuNUFFTOp->performForwardGpuNUFFT(imgArray);
    
    printf("contrast %f \n",kSpace.data[0].x/kSpace.data[1].x);

    free(data);
    free(coords);
    free(gdata);

    delete gpuNUFFTOp;
  }
  \endcode
*/
