870 lines
29 KiB
C++
870 lines
29 KiB
C++
// ____ ______ __
|
|
// / __ \ / ____// /
|
|
// / /_/ // / / /
|
|
// / ____// /___ / /___ PixInsight Class Library
|
|
// /_/ \____//_____/ PCL 2.4.23
|
|
// ----------------------------------------------------------------------------
|
|
// pcl/FFT2D.h - Released 2022-03-12T18:59:29Z
|
|
// ----------------------------------------------------------------------------
|
|
// This file is part of the PixInsight Class Library (PCL).
|
|
// PCL is a multiplatform C++ framework for development of PixInsight modules.
|
|
//
|
|
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
|
|
//
|
|
// Redistribution and use in both source and binary forms, with or without
|
|
// modification, is permitted provided that the following conditions are met:
|
|
//
|
|
// 1. All redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. All redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
|
|
// of their contributors, may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission. For written
|
|
// permission, please contact info@pixinsight.com.
|
|
//
|
|
// 4. All products derived from this software, in any form whatsoever, must
|
|
// reproduce the following acknowledgment in the end-user documentation
|
|
// and/or other materials provided with the product:
|
|
//
|
|
// "This product is based on software from the PixInsight project, developed
|
|
// by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
|
|
//
|
|
// Alternatively, if that is where third-party acknowledgments normally
|
|
// appear, this acknowledgment must be reproduced in the product itself.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
|
|
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
|
|
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#ifndef __PCL_FFT2D_h
|
|
#define __PCL_FFT2D_h
|
|
|
|
/// \file pcl/FFT2D.h
|
|
|
|
/*
|
|
* The FFT routines used in this PCL version are based on the KISS FFT library
|
|
* by Mark Borgerding: http://sourceforge.net/projects/kissfft/
|
|
*
|
|
* KISS FFT LICENSE INFORMATION
|
|
* ============================
|
|
*
|
|
* Copyright (c) 2003-2009 Mark Borgerding
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* * Neither the author nor the names of any contributors may be used to
|
|
* endorse or promote products derived from this software without specific
|
|
* prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <pcl/Defs.h>
|
|
|
|
#include <pcl/FFT1D.h>
|
|
#include <pcl/Matrix.h>
|
|
#include <pcl/ParallelProcess.h>
|
|
#include <pcl/StatusMonitor.h>
|
|
|
|
namespace pcl
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class FFT2DBase
|
|
{
|
|
protected:
|
|
|
|
static void Transform( int, int, fcomplex*, const fcomplex*, int, StatusMonitor*, bool, int );
|
|
static void Transform( int, int, dcomplex*, const dcomplex*, int, StatusMonitor*, bool, int );
|
|
static void Transform( int, int, fcomplex*, const float*, StatusMonitor*, bool, int );
|
|
static void Transform( int, int, dcomplex*, const double*, StatusMonitor*, bool, int );
|
|
static void Transform( int, int, float*, const fcomplex*, StatusMonitor*, bool, int );
|
|
static void Transform( int, int, double*, const dcomplex*, StatusMonitor*, bool, int );
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class AbstractFFT2D
|
|
* \brief Abstract base class of all two-dimensional fast Fourier transform classes
|
|
*
|
|
* The %AbstractFFT2D template class implements basic properties and functions
|
|
* shared by all 2-D %FFT PCL classes.
|
|
*
|
|
* \sa GenericFFT2D, GenericRealFFT2D
|
|
*/
|
|
template <typename T>
|
|
class PCL_CLASS AbstractFFT2D : public FFT2DBase, public ParallelProcess
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Represents a scalar in the context of this %FFT class.
|
|
*/
|
|
typedef T scalar;
|
|
|
|
/*!
|
|
* Represents a complex number in the context of this %FFT class.
|
|
*/
|
|
typedef Complex<T> complex;
|
|
|
|
/*!
|
|
* Represents a vector of real numbers.
|
|
*/
|
|
typedef GenericVector<scalar> vector;
|
|
|
|
/*!
|
|
* Represents a vector of complex numbers.
|
|
*/
|
|
typedef GenericVector<complex> complex_vector;
|
|
|
|
/*!
|
|
* Represents a real matrix.
|
|
*/
|
|
typedef GenericMatrix<scalar> matrix;
|
|
|
|
/*!
|
|
* Represents a complex matrix.
|
|
*/
|
|
typedef GenericMatrix<complex> complex_matrix;
|
|
|
|
/*!
|
|
* Represents a discrete Fourier transform matrix.
|
|
*/
|
|
typedef complex_matrix transform;
|
|
|
|
/*!
|
|
* Constructs an %AbstractFFT2D object of the specified dimensions
|
|
* \a rows and \a cols.
|
|
*/
|
|
AbstractFFT2D( int rows, int cols )
|
|
: m_rows( rows )
|
|
, m_cols( cols )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Constructs an %AbstractFFT2D object of the specified dimensions
|
|
* \a rows and \a cols, using the specified status \a monitor object.
|
|
*
|
|
* On each transform performed with this object, the status monitor will be
|
|
* incremented by the sum of transform dimensions: \a rows + \a cols.
|
|
*/
|
|
AbstractFFT2D( int rows, int cols, StatusMonitor& monitor )
|
|
: m_rows( rows )
|
|
, m_cols( cols )
|
|
, m_monitor( &monitor )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Virtual destructor.
|
|
*
|
|
* Destroys all internal control structures in this %AbstractFFT2D object,
|
|
* including the current discrete Fourier transform, if exists.
|
|
*/
|
|
virtual ~AbstractFFT2D()
|
|
{
|
|
Release();
|
|
}
|
|
|
|
/*!
|
|
* Returns the number of rows in the 2-D transform of this %AbstractFFT2D
|
|
* object. Transform dimensions are specified in the constructors of all 2-D
|
|
* %FFT classes.
|
|
*/
|
|
int Rows() const
|
|
{
|
|
return m_rows;
|
|
}
|
|
|
|
/*!
|
|
* Returns the number of columns in the 2-D transform of this %AbstractFFT2D
|
|
* object. Transform dimensions are specified in the constructors of all 2-D
|
|
* %FFT classes.
|
|
*/
|
|
int Cols() const
|
|
{
|
|
return m_cols;
|
|
}
|
|
|
|
/*!
|
|
* Returns the total number of matrix elements in the 2-D data set of this
|
|
* %AbstractFFT2D object, or Rows() multiplied by Cols(). The dimensions are
|
|
* specified in the constructors of all 2-D %FFT classes.
|
|
*/
|
|
int NumberOfElements() const
|
|
{
|
|
return m_rows*m_cols;
|
|
}
|
|
|
|
/*!
|
|
* Returns a duplicate of the current discrete Fourier transform as a matrix
|
|
* of complex values.
|
|
*
|
|
* For complex data transforms, the returned matrix has Rows()*Cols()
|
|
* elements. For real data, the returned matrix has Rows()*(Cols()/2 + 1)
|
|
* elements.
|
|
*
|
|
* If no %FFT has been performed on this object, this function returns an
|
|
* empty matrix.
|
|
*/
|
|
transform DFT() const
|
|
{
|
|
return m_dft;
|
|
}
|
|
|
|
/*!
|
|
* Returns a non-const reference to the current discrete Fourier transform
|
|
* in this object. The transform is a matrix of complex values.
|
|
*
|
|
* For complex data transforms, the returned matrix has Rows()*Cols()
|
|
* elements. For real data, the returned matrix has Rows()*(Cols()/2 + 1)
|
|
* elements.
|
|
*
|
|
* If no %FFT has been performed on this object, this function returns a
|
|
* reference to an empty matrix.
|
|
*/
|
|
transform& DFT()
|
|
{
|
|
return m_dft;
|
|
}
|
|
|
|
/*!
|
|
* Destroys all internal control structures in this %FFT object, including
|
|
* the current Fourier transform, if exists.
|
|
*/
|
|
virtual void Release()
|
|
{
|
|
m_dft = transform();
|
|
}
|
|
|
|
private:
|
|
|
|
// Transform dimensions
|
|
int m_rows;
|
|
int m_cols;
|
|
|
|
protected:
|
|
|
|
transform m_dft; // DFT of complex or real data
|
|
StatusMonitor* m_monitor = nullptr;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#define m_dft this->m_dft
|
|
#define m_rows this->Rows()
|
|
#define m_cols this->Cols()
|
|
#define m_monitor this->m_monitor
|
|
#define m_parallel this->m_parallel
|
|
#define m_maxProcessors this->m_maxProcessors
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class GenericFFT2D
|
|
* \brief Generic two-dimensional fast Fourier transform of complex data
|
|
*
|
|
* The %GenericFFT2D template class performs two-dimensional forward and
|
|
* inverse, out-of-place fast Fourier transforms of complex data.
|
|
*
|
|
* For fast Fourier transforms of 2-D real-valued data, see the
|
|
* GenericRealFFT2D template class.
|
|
*
|
|
* \sa AbstractFFT2D, GenericRealFFT2D
|
|
*/
|
|
template <typename T>
|
|
class PCL_CLASS GenericFFT2D : public AbstractFFT2D<T>
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Identifies the base class of this %FFT class.
|
|
*/
|
|
typedef AbstractFFT2D<T> base;
|
|
|
|
/*!
|
|
* Represents a scalar in the context of this %FFT class.
|
|
*/
|
|
typedef typename base::scalar scalar;
|
|
|
|
/*!
|
|
* Represents a complex number in the context of this %FFT class.
|
|
*/
|
|
typedef typename base::complex complex;
|
|
|
|
/*!
|
|
* Represents a vector of real numbers.
|
|
*/
|
|
typedef typename base::vector vector;
|
|
|
|
/*!
|
|
* Represents a vector of complex numbers.
|
|
*/
|
|
typedef typename base::complex_vector complex_vector;
|
|
|
|
/*!
|
|
* Represents a real matrix.
|
|
*/
|
|
typedef typename base::matrix matrix;
|
|
|
|
/*!
|
|
* Represents a complex matrix.
|
|
*/
|
|
typedef typename base::complex_matrix complex_matrix;
|
|
|
|
/*!
|
|
* Represents a discrete Fourier transform matrix.
|
|
*/
|
|
typedef typename base::transform transform;
|
|
|
|
/*!
|
|
* Constructs a %GenericFFT2D object of the specified dimensions \a rows and
|
|
* \a cols.
|
|
*
|
|
* The current PCL implementation supports FFTs of arbitrary length, but the
|
|
* underlying routines have been optimized for performance when the length
|
|
* of the input vector can be factorized as follows:
|
|
*
|
|
* <tt>n = 2^n2 * 3^n3 * 4^n4 * 5^n5</tt>
|
|
*
|
|
* where n2, n3, n4, and n5 are arbitrary positive integers. For best
|
|
* performance, you should call GenericFFT2D::OptimizedLength() to get the
|
|
* smallest optimal dimensions for your data, then place them on a matrix of
|
|
* the obtained dimensions, padded with zeros.
|
|
*/
|
|
GenericFFT2D( int rows, int cols )
|
|
: base( rows, cols )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Constructs a %GenericFFT2D object of the specified dimensions \a rows and
|
|
* \a cols, using the specified status monitoring object \a status.
|
|
*
|
|
* On each transform performed with this object, the status m_monitor will be
|
|
* incremented by the sum of transform dimensions: \a rows + \a cols.
|
|
*
|
|
* See the GenericFFT2D( int, int ) constructor for more information.
|
|
*/
|
|
GenericFFT2D( int rows, int cols, StatusMonitor& status )
|
|
: base( rows, cols, status )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Virtual destructor.
|
|
*/
|
|
virtual ~GenericFFT2D()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Fast Fourier transform. Performs the two-dimensional %FFT of the
|
|
* specified matrix of complex values.
|
|
*
|
|
* The argument \a x must be the starting address of a contiguous block of
|
|
* at least NumberOfElements() elements, stored in row order: all elements
|
|
* of the first matrix row followed by all elements of the second row, and
|
|
* so on.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericFFT2D& operator <<( const complex* x )
|
|
{
|
|
if ( m_dft.IsEmpty() )
|
|
m_dft = transform( m_rows, m_cols );
|
|
this->Transform( m_rows, m_cols, *m_dft, x, PCL_FFT_FORWARD, m_monitor, m_parallel, m_maxProcessors );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Inverse fast Fourier transform. Performs the two-dimensional inverse %FFT
|
|
* and stores the result in the specified matrix of complex values.
|
|
*
|
|
* The argument \a y must be the starting address of a contiguous block of
|
|
* at least NumberOfElements() elements. The result matrix will be stored in
|
|
* row order: all elements of the first matrix row followed by all elements
|
|
* of the second row, and so on.
|
|
*
|
|
* If no %FFT has been performed on this object (by a previous call to
|
|
* operator <<()), this member function throws an Error exception.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericFFT2D& operator >>( complex* y ) const
|
|
{
|
|
if ( m_dft.IsEmpty() )
|
|
throw Error( "Invalid out-of-place inverse FFT: No FFT has been performed." );
|
|
this->Transform( m_rows, m_cols, y, *m_dft, PCL_FFT_BACKWARD, m_monitor, m_parallel, m_maxProcessors );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Fast Fourier transform. Performs the two-dimensional %FFT of a matrix of
|
|
* complex values.
|
|
*
|
|
* The specified matrix \a x must have Rows() and Cols() dimensions.
|
|
* Otherwise an Error exception will be thrown.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericFFT2D& operator <<( const complex_matrix& x )
|
|
{
|
|
PCL_PRECONDITION( x.Rows() == m_rows )
|
|
PCL_PRECONDITION( x.Cols() == m_cols )
|
|
if ( x.Rows() != m_rows || x.Cols() != m_cols )
|
|
throw Error( "Invalid FFT input matrix dimensions." );
|
|
return operator <<( *x );
|
|
}
|
|
|
|
/*!
|
|
* Inverse fast Fourier transform. Performs the two-dimensional inverse %FFT
|
|
* and stores the result in a matrix of complex values.
|
|
*
|
|
* The specified matrix \a y must have Rows() and Cols() dimensions.
|
|
* Otherwise an Error exception will be thrown.
|
|
*
|
|
* If no %FFT has been performed on this object (by a previous call to
|
|
* operator <<()), this member function throws an Error exception.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericFFT2D& operator >>( complex_matrix& y ) const
|
|
{
|
|
PCL_PRECONDITION( y.Rows() == m_rows )
|
|
PCL_PRECONDITION( y.Cols() == m_cols )
|
|
if ( y.Rows() != m_rows || y.Cols() != m_cols )
|
|
throw Error( "Invalid FFT output matrix dimensions." );
|
|
return operator >>( *y );
|
|
}
|
|
|
|
/*!
|
|
* Performs the forward or inverse two-dimensional %FFT of an input matrix
|
|
* of complex values, and stores the result in a caller-supplied output
|
|
* matrix.
|
|
*
|
|
* \param[in] x Input matrix. Must be the starting address of a contiguous
|
|
* sequence of at least NumberOfElements() complex numbers,
|
|
* stored in row order: all elements of the first row
|
|
* followed by all elements of the second row, and so on.
|
|
*
|
|
* \param[out] y Output matrix, where the result of the transform will be
|
|
* stored. Must be the starting address of a contiguous
|
|
* sequence of at least NumberOfElements() complex numbers.
|
|
* The result will be stored in row order: all elements of
|
|
* the first row followed by all elements of the second row,
|
|
* and so on.
|
|
*
|
|
* \param dir Indicates the direction of the Fourier transform:\n
|
|
* \n
|
|
* <table border="1" cellpadding="4" cellspacing="0">
|
|
* <tr><td>PCL_FFT_FORWARD</td> <td>The FFT is calculated.</td></tr>
|
|
* <tr><td>PCL_FFT_BACKWARD</td> <td>The inverse FFT is calculated.</td></tr>
|
|
* </table>\n
|
|
* \n
|
|
* This parameter is optional; the default value is
|
|
* PCL_FFT_FORWARD.
|
|
*
|
|
* This member function does not change the current Fourier transform in
|
|
* this object, if it exists.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericFFT2D& operator ()( complex* y, const complex* x, int dir = PCL_FFT_FORWARD ) const
|
|
{
|
|
this->Transform( m_rows, m_cols, y, x, dir, m_monitor, m_parallel, m_maxProcessors );
|
|
return const_cast<GenericFFT2D&>( *this );
|
|
}
|
|
|
|
/*!
|
|
* Returns the <em>optimized complex %FFT length</em> larger than or equal to
|
|
* a given length \a n. The returned length will be optimal to perform a
|
|
* %FFT of complex data with the current PCL implementation. The optimized
|
|
* length can be used as the \a rows or \a cols argument to the constructor
|
|
* of any two-dimensional %FFT class for complex data transforms.
|
|
*/
|
|
static int OptimizedLength( int n )
|
|
{
|
|
return GenericFFT<T>::OptimizedLength( n );
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class GenericRealFFT2D
|
|
* \brief Generic two-dimensional fast Fourier transform of real data
|
|
*
|
|
* The %GenericRealFFT2D template class performs forward and inverse,
|
|
* out-of-place fast two-dimensional Fourier transforms of real-valued data.
|
|
* For real data in the time domain, this class performs nearly twice as fast
|
|
* as Fourier transform classes for complex data.
|
|
*
|
|
* For two-dimensional fast Fourier transforms of complex-valued data, see the
|
|
* GenericFFT2D template class.
|
|
*
|
|
* \sa AbstractFFT2D, GenericFFT2D
|
|
*/
|
|
template <typename T>
|
|
class PCL_CLASS GenericRealFFT2D : public AbstractFFT2D<T>
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Identifies the base class of this %FFT class.
|
|
*/
|
|
typedef AbstractFFT2D<T> base;
|
|
|
|
/*!
|
|
* Represents a scalar in the context of this %FFT class.
|
|
*/
|
|
typedef typename base::scalar scalar;
|
|
|
|
/*!
|
|
* Represents a complex number in the context of this %FFT class.
|
|
*/
|
|
typedef typename base::complex complex;
|
|
|
|
/*!
|
|
* Represents a vector of real numbers.
|
|
*/
|
|
typedef typename base::vector vector;
|
|
|
|
/*!
|
|
* Represents a vector of complex numbers.
|
|
*/
|
|
typedef typename base::complex_vector complex_vector;
|
|
|
|
/*!
|
|
* Represents a real matrix.
|
|
*/
|
|
typedef typename base::matrix matrix;
|
|
|
|
/*!
|
|
* Represents a complex matrix.
|
|
*/
|
|
typedef typename base::complex_matrix complex_matrix;
|
|
|
|
/*!
|
|
* Represents a discrete Fourier transform matrix.
|
|
*/
|
|
typedef typename base::transform transform;
|
|
|
|
/*!
|
|
* Constructs a %GenericRealFFT2D object of the specified dimensions \a rows
|
|
* and \a cols.
|
|
*
|
|
* The current PCL implementation supports FFTs for real data of any even
|
|
* length, but the underlying routines have been optimized for performance
|
|
* when the length of the input vector can be factorized as follows:
|
|
*
|
|
* <tt>n = 2^n2 * 3^n3 * 4^n4 * 5^n5</tt>
|
|
*
|
|
* where n2, n3, n4, and n5 are arbitrary positive integers, and n is an
|
|
* even integer. For best performance, you should call
|
|
* GenericRealFFT2D::OptimizedLength() to get the smallest optimal
|
|
* dimensions for your real-valued data, then place them on a matrix of the
|
|
* obtained dimensions, padded with zeros.
|
|
*
|
|
* \note We stress the fact that the specified dimensions \a rows and
|
|
* \a cols must be \e even integer numbers.
|
|
*/
|
|
GenericRealFFT2D( int rows, int cols )
|
|
: base( rows, cols )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Constructs a %GenericRealFFT2D object of the specified dimensions \a rows
|
|
* and \a cols, using the specified status monitoring object \a status.
|
|
*
|
|
* On each transform performed with this object, the status m_monitor will be
|
|
* incremented by the sum of transform dimensions: \a rows + \a cols.
|
|
*
|
|
* See the GenericRealFFT2D( int, int ) constructor for more information.
|
|
*/
|
|
GenericRealFFT2D( int rows, int cols, StatusMonitor& status )
|
|
: base( rows, cols, status )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Virtual destructor.
|
|
*/
|
|
virtual ~GenericRealFFT2D()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Fast Fourier transform. Performs the two-dimensional %FFT of the
|
|
* specified matrix of real values.
|
|
*
|
|
* The argument \a x must be the starting address of a contiguous block of
|
|
* at least NumberOfElements() elements, stored in row order: all elements
|
|
* of the first matrix row followed by all elements of the second row, and
|
|
* so on.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericRealFFT2D& operator <<( const scalar* x )
|
|
{
|
|
if ( m_dft.IsEmpty() )
|
|
m_dft = transform( m_rows, m_cols/2 + 1 );
|
|
this->Transform( m_rows, m_cols, *m_dft, x, m_monitor, m_parallel, m_maxProcessors );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Inverse fast Fourier transform. Performs the two-dimensional inverse %FFT
|
|
* and stores the result in the specified matrix of real values.
|
|
*
|
|
* The argument \a y must be the starting address of a contiguous block of
|
|
* at least NumberOfElements() elements. The result matrix will be stored in
|
|
* row order: all elements of the first matrix row followed by all elements
|
|
* of the second row, and so on.
|
|
*
|
|
* If no %FFT has been performed on this object (by a previous call to
|
|
* operator <<()), this member function throws an Error exception.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericRealFFT2D& operator >>( scalar* y ) const
|
|
{
|
|
if ( m_dft.IsEmpty() )
|
|
throw Error( "Invalid out-of-place inverse FFT: No FFT has been performed." );
|
|
this->Transform( m_rows, m_cols, y, *m_dft, m_monitor, m_parallel, m_maxProcessors );
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* Fast Fourier transform. Performs the two-dimensional %FFT of a matrix of
|
|
* real numbers.
|
|
*
|
|
* The specified matrix \a x must have Rows() and Cols() dimensions.
|
|
* Otherwise an Error exception will be thrown.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericRealFFT2D& operator <<( const matrix& x )
|
|
{
|
|
PCL_PRECONDITION( x.Rows() == m_rows )
|
|
PCL_PRECONDITION( x.Cols() == m_cols )
|
|
if ( x.Rows() != m_rows || x.Cols() != m_cols )
|
|
throw Error( "Invalid FFT input matrix dimensions." );
|
|
return operator <<( *x );
|
|
}
|
|
|
|
/*!
|
|
* Inverse fast Fourier transform. Performs the two-dimensional inverse %FFT
|
|
* and stores the result in a matrix of real numbers.
|
|
*
|
|
* The specified matrix \a y must have Rows() and Cols() dimensions.
|
|
* Otherwise an Error exception will be thrown.
|
|
*
|
|
* If no %FFT has been performed on this object (by a previous call to
|
|
* operator <<()), this member function throws an Error exception.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericRealFFT2D& operator >>( matrix& y ) const
|
|
{
|
|
PCL_PRECONDITION( y.Rows() == m_rows )
|
|
PCL_PRECONDITION( y.Cols() == m_cols )
|
|
if ( y.Rows() != m_rows || y.Cols() != m_cols )
|
|
throw Error( "Invalid FFT output matrix dimensions." );
|
|
return operator >>( *y );
|
|
}
|
|
|
|
/*!
|
|
* Performs the two-dimensional %FFT of an input matrix of real numbers, and
|
|
* stores the result in an output matrix of complex numbers.
|
|
*
|
|
* \param[in] x Input matrix. Must be the starting address of a contiguous
|
|
* sequence of at least NumberOfElements() real numbers,
|
|
* stored in row order: all elements of the first row
|
|
* followed by all elements of the second row, and so on.
|
|
*
|
|
* \param[out] y Output matrix, where the result of the transform will be
|
|
* stored. Must be the starting address of a contiguous
|
|
* sequence of at least Rows()*(Cols()/2 + 1) complex
|
|
* numbers. The result will be stored in row order: all
|
|
* elements of the first row followed by all elements of the
|
|
* second row, and so on, where each row has Cols()/2 + 1
|
|
* complex numbers.
|
|
*
|
|
* The output matrix will have Rows() rows and Cols()/2 + 1 columns, stored
|
|
* in row order.
|
|
*
|
|
* This member function does not change the current Fourier transform in
|
|
* this object, if it exists.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericRealFFT2D& operator()( complex* y, const scalar* x ) const
|
|
{
|
|
this->Transform( m_rows, m_cols, y, x, m_monitor, m_parallel, m_maxProcessors );
|
|
return const_cast<GenericRealFFT2D&>( *this );
|
|
}
|
|
|
|
/*!
|
|
* Performs the inverse two-dimensional %FFT of an input matrix of complex
|
|
* numbers, and stores the result in an output matrix of real numbers.
|
|
*
|
|
* \param[in] x Input matrix. Must be the starting address of a contiguous
|
|
* sequence of at least Rows()*(Cols()/2 + 1) complex
|
|
* numbers, stored in row order: all elements of the first
|
|
* row followed by all elements of the second row, and so on,
|
|
* where each row must have Cols()/2 + 1 complex numbers.
|
|
*
|
|
* \param[out] y Output matrix, where the result of the transform will be
|
|
* stored. Must be the starting address of a contiguous
|
|
* sequence of at least NumberOfElements() real numbers. The
|
|
* result will be stored in row order: all elements of the
|
|
* first row followed by all elements of the second row, and
|
|
* so on.
|
|
*
|
|
* The input matrix must have Rows() rows and Cols()/2 + 1 columns, stored
|
|
* in row order.
|
|
*
|
|
* This member function does not change the current Fourier transform in
|
|
* this object, if it exists.
|
|
*
|
|
* Returns a reference to this object.
|
|
*/
|
|
GenericRealFFT2D& operator()( scalar* y, const complex* x ) const
|
|
{
|
|
this->Transform( m_rows, m_cols, y, x, m_monitor, m_parallel, m_maxProcessors );
|
|
return const_cast<GenericRealFFT2D&>( *this );
|
|
}
|
|
|
|
/*!
|
|
* Returns the <em>optimized complex %FFT length</em> larger than or equal to
|
|
* a given length \a n. The returned length will be optimal to perform a
|
|
* %FFT of real data with the current PCL implementation. The optimized
|
|
* length can be used as the \a rows or \a cols argument to the constructor
|
|
* of any two-dimensional %FFT class for real-valued data transforms.
|
|
*/
|
|
static int OptimizedLength( int n )
|
|
{
|
|
return GenericFFT<T>::OptimizedLength( n );
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#undef m_dft
|
|
#undef m_rows
|
|
#undef m_cols
|
|
#undef m_monitor
|
|
#undef m_parallel
|
|
#undef m_maxProcessors
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \defgroup fft_2d Two-Dimensional Fast Fourier Transforms
|
|
*/
|
|
|
|
#ifndef __PCL_NO_FFT2D_INSTANTIATE
|
|
|
|
/*!
|
|
* \class pcl::FFFT2D
|
|
* \ingroup fft_2d
|
|
* \brief Fast Fourier transform of 32-bit floating point complex data.
|
|
*
|
|
* %FFFT2D is a template instantiation of GenericFFT2D for the \c float type.
|
|
*/
|
|
typedef GenericFFT2D<float> FFFT2D;
|
|
|
|
/*!
|
|
* \class pcl::DFFT2D
|
|
* \ingroup fft_2d
|
|
* \brief Fast Fourier transform of 64-bit floating point complex data.
|
|
*
|
|
* %DFFT2D is a template instantiation of GenericFFT2D for the \c double type.
|
|
*/
|
|
typedef GenericFFT2D<double> DFFT2D;
|
|
|
|
/*!
|
|
* \class pcl::FRealFFT2D
|
|
* \ingroup fft_2d
|
|
* \brief Fast Fourier transform of 32-bit floating point real data.
|
|
*
|
|
* %FRealFFT2D is a template instantiation of GenericRealFFT2DT for \c float.
|
|
*/
|
|
typedef GenericRealFFT2D<float> FRealFFT2D;
|
|
|
|
/*!
|
|
* \class pcl::DRealFFT2D
|
|
* \ingroup fft_2d
|
|
* \brief Fast Fourier transform of 64-bit floating point real data.
|
|
*
|
|
* %DRealFFT2D is a template instantiation of GenericRealFFT2D for \c double.
|
|
*/
|
|
typedef GenericRealFFT2D<double> DRealFFT2D;
|
|
|
|
/*!
|
|
* \class pcl::FFT2D
|
|
* \ingroup fft_2d
|
|
* \brief Fast Fourier transform of 32-bit floating point complex data.
|
|
*
|
|
* %FFT2D is an alias for FFFT2D. It is a template instantiation of
|
|
* GenericFFT2D for the \c float type.
|
|
*/
|
|
typedef FFFT2D FFT2D;
|
|
|
|
/*!
|
|
* \class pcl::RealFFT2D
|
|
* \ingroup fft_2d
|
|
* \brief Fast Fourier transform of 32-bit floating point real data.
|
|
*
|
|
* %RealFFT2D is an alias for FRealFFT2D. It is a template instantiation of
|
|
* GenericRealFFT2D for the \c float type.
|
|
*/
|
|
typedef FRealFFT2D RealFFT2D;
|
|
|
|
#endif // __PCL_NO_FFT2D_INSTANTIATE
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
} // pcl
|
|
|
|
#endif // __PCL_FFT2D_h
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// EOF pcl/FFT2D.h - Released 2022-03-12T18:59:29Z
|