LCOV - code coverage report
Current view: top level - math/ft - ftUtils.hpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 26.1 % 23 6
Test Date: 2026-02-19 16:58:26 Functions: 50.0 % 2 1

            Line data    Source code
       1              : /** \file ftUtils.hpp
       2              :  * \brief Fourier Transform Utilities
       3              :  * \ingroup ft_files
       4              :  * \author Jared R. Males (jaredmales@gmail.com)
       5              :  *
       6              :  */
       7              : 
       8              : //***********************************************************************//
       9              : // Copyright 2025 Jared R. Males (jaredmales@gmail.com)
      10              : //
      11              : // This file is part of mxlib.
      12              : //
      13              : // mxlib is free software: you can redistribute it and/or modify
      14              : // it under the terms of the GNU General Public License as published by
      15              : // the Free Software Foundation, either version 3 of the License, or
      16              : // (at your option) any later version.
      17              : //
      18              : // mxlib is distributed in the hope that it will be useful,
      19              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      20              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21              : // GNU General Public License for more details.
      22              : //
      23              : // You should have received a copy of the GNU General Public License
      24              : // along with mxlib.  If not, see <http://www.gnu.org/licenses/>.
      25              : //***********************************************************************//
      26              : 
      27              : #ifndef ftUtils_hpp
      28              : #define ftUtils_hpp
      29              : 
      30              : namespace mx
      31              : {
      32              : namespace math
      33              : {
      34              : namespace ft
      35              : {
      36              : 
      37              : /// Add padding to the output of a real-to-complex (R2C) FFT
      38              : /**
      39              :  * The output array should be pre-sized according to:
      40              :  * \verbatim
      41              :  * aout.cols() == ain.cols() + padCols
      42              :  * aout.rows() == ain.rows() + padRows
      43              :  * \endverbatim
      44              :  * where `padRows` and `padCols are the desired amount of padding. \p aout will be in
      45              :  * FFT order and suitable for input to the inverse transform (complext-to-real).
      46              :  *
      47              :  * \ingroup ft
      48              :  */
      49              : template <class eigenArrOutT, class eigenArrInT>
      50           24 : void padR2CFFTOutput( eigenArrOutT &aout, /**< [out] The padded array.  Must be pre-allocated. The pad region will
      51              :                                                     not be set to zero.  Size of the pad is determined by the
      52              :                                                     difference in size between \p aout and \p ain*/
      53              :                       eigenArrInT &ain /**< [in] The array to be paddded, in real-to-complex FFTW storage order.*/ )
      54              : {
      55           24 :     int ci = 0.5 * ain.cols() + 1;
      56           24 :     int cf = ain.cols() - ci;
      57              : 
      58           24 :     aout.block( 0, 0, ain.rows(), ci ) = ain.block( 0, 0, ain.rows(), ci );
      59           24 :     aout.block( 0, aout.cols() - cf, ain.rows(), cf ) = ain.block( 0, ain.cols() - cf, ain.rows(), cf );
      60           24 : }
      61              : 
      62              : /// Add padding to the output of a complex-to-complex (C2C) FFT
      63              : /** The output array should be pre-sized according to:
      64              :  * \verbatim
      65              :  * aout.row() ==  ain.rows() + padRows
      66              :  * aout.cols() == ain.cols() + padCols
      67              :  * \endverbatim
      68              :  * where `padRows` and `padCols are the desired amount of padding. \p aout will be in
      69              :  * FFT order and suitable for input to the inverse transform (complex-to-complex).
      70              :  *
      71              :  * \ingroup ft
      72              :  */
      73              : template <class eigenArrOutT, class eigenArrInT>
      74              : void padC2CFFTOutput( eigenArrOutT &aout, /**< [out] The padded array.  Must be pre-allocated. The pad region will
      75              :                                                      not be set to zero.  Size of the pad is determined by the
      76              :                                                      difference in size between \p aout and \p ain*/
      77              :                       eigenArrInT &ain /**< [in] The array to be paddded, in complex-to-complex
      78              :                                                  FFTW storage order.*/ )
      79              : {
      80              :     int ri = 0.5 * ain.rows() + 1;
      81              :     int ci = 0.5 * ain.cols() + 1;
      82              : 
      83              :     int rf = ain.rows() - ri;
      84              :     int cf = ain.cols() - ci;
      85              : 
      86              :     aout.topLeftCorner( ri, ci ) = ain.topLeftCorner( ri, ci );
      87              :     aout.bottomLeftCorner( rf, ci ) = ain.bottomLeftCorner( rf, ci );
      88              :     aout.topRightCorner( ri, cf ) = ain.topRightCorner( ri, cf );
      89              :     aout.bottomRightCorner( rf, cf ) = ain.bottomRightCorner( rf, cf );
      90              : }
      91              : 
      92              : /// Augment and pad the output of a real-to-complex (R2C) forward FFT for use with a complex-to-complex (C2C) inverse
      93              : /// FFT
      94              : /** The output array should be pre-sized according to:
      95              :  *  \verbatim
      96              :  *   aout.row() == 2*(ain.rows()-1) + padRows
      97              :  *   aout.cols() == ain.cols() + padCols
      98              :  * \endverbatim
      99              :  * where padRows and padCols can be 0. \p aout will be in
     100              :  * FFT order and suitable for input to the inverse transform (complex-to-complex).
     101              :  *
     102              :  * \ingroup ft
     103              :  */
     104              : template <class eigenArrOutT, class eigenArrInT>
     105            0 : void augmentR2CFFTOutput( eigenArrOutT &aout, eigenArrInT &ain )
     106              : {
     107              : 
     108            0 :     int padRows = aout.rows() - ain.rows();
     109            0 :     int padCols = aout.cols() - ain.cols();
     110              : 
     111              :     // aout.resize( 2 * ( ain.rows() - 1 ) + padRows, ain.cols() + padCols );
     112              : 
     113            0 :     int r1 = ain.rows();
     114            0 :     int c1 = 0.5 * ain.cols() + 1;
     115              : 
     116            0 :     int r2 = aout.rows() - ( r1 + padRows );
     117            0 :     int c2 = aout.cols() - ( c1 + padCols );
     118              : 
     119            0 :     aout.block( 0, 0, r1, c1 ) = ain.block( 0, 0, r1, c1 );
     120              : 
     121            0 :     aout.block( 0, c1 + padCols, r1, c2 ) = ain.block( 0, c1, r1, c2 );
     122              : 
     123              :     // Upper Right corner
     124            0 :     for( int cc = 1; cc < c1 - 1; ++cc )
     125              :     {
     126            0 :         for( int rr = 1; rr < r1 - 1; ++rr )
     127              :         {
     128            0 :             aout( aout.rows() - rr, aout.cols() - cc ) = conj( ain( rr, cc ) );
     129              :         }
     130              :     }
     131              : 
     132              :     // Lower Right corner
     133            0 :     for( int rr = 1; rr < ain.rows() - 1; ++rr )
     134              :     {
     135            0 :         aout( aout.rows() - rr, 0 ) = conj( ain( rr, 0 ) );
     136              : 
     137              :         // After ain.rows()+1, for column 1 and greater, the columns are reversed and conjugate
     138            0 :         aout.block( aout.rows() - rr, 1, 1, aout.cols() - padCols - c1 + 1 ) =
     139            0 :             conj( ain.block( rr, c1 - 1, 1, ain.cols() - c1 + 1 ).reverse() );
     140              :     }
     141            0 : }
     142              : 
     143              : } // namespace ft
     144              : } // namespace math
     145              : } // namespace mx
     146              : 
     147              : #endif // ftUtils_hpp
        

Generated by: LCOV version 2.0-1