From: IOhannes m zmölnig (Debian/GNU) Date: Sat, 17 Jun 2023 17:55:11 +0000 (+0200) Subject: Add missing sources X-Git-Tag: archive/raspbian/2.5.1+ds-1+rpi1~1^2~74 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a1b19c563023425f601806f0f9b4f9c3db6712c8;p=jacktrip.git Add missing sources --- diff --git a/debian/copyright b/debian/copyright index ed78a8e..579d2ca 100644 --- a/debian/copyright +++ b/debian/copyright @@ -42,6 +42,10 @@ Files: debian/* Copyright: 2010-2023, IOhannes m zmölnig License: Expat +Files: debian/missing-sources/Simple-FFT/* +Copyright: 2013-2020, Dmitry Ivanov +License: Expat + License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/debian/missing-sources/Simple-FFT/include/simple_fft/check_fft.hpp b/debian/missing-sources/Simple-FFT/include/simple_fft/check_fft.hpp new file mode 100644 index 0000000..b1b95c9 --- /dev/null +++ b/debian/missing-sources/Simple-FFT/include/simple_fft/check_fft.hpp @@ -0,0 +1,571 @@ +/** + * Copyright (c) 2013-2020 Dmitry Ivanov + * + * This file is a part of Simple-FFT project and is distributed under the terms + * of MIT license: https://opensource.org/licenses/MIT + */ + +#ifndef __SIMPLE_FFT__CHECK_FFT_HPP__ +#define __SIMPLE_FFT__CHECK_FFT_HPP__ + +#include "fft_settings.h" +#include "error_handling.hpp" +#include "copy_array.hpp" +#include +#include +#include + +using std::size_t; + +namespace simple_fft { +namespace check_fft_private { + +enum CheckMode +{ + CHECK_FFT_PARSEVAL, + CHECK_FFT_ENERGY, + CHECK_FFT_EQUALITY +}; + +template +void getMaxAbsoluteAndRelativeErrorNorms(const TArray1D & array1, + const TComplexArray1D & array2, const size_t size, + real_type & max_absolute_error_norm, + real_type & max_relative_error_norm) +{ + using std::abs; + + real_type current_error; + + // NOTE: no parallelization here, it is a completely sequential loop! + for(size_t i = 0; i < size; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + current_error = abs(array1[i] - array2[i]); +#else + current_error = abs(array1(i) - array2(i)); +#endif + if (current_error > max_absolute_error_norm) { + max_absolute_error_norm = current_error; +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + if (abs(array1[i]) > abs(array2[i])) { + max_relative_error_norm = (abs(array1[i]) > 1e-20 + ? max_absolute_error_norm / abs(array1[i]) + : 0.0); + } + else { + max_relative_error_norm = (abs(array2[i]) > 1e-20 + ? max_absolute_error_norm / abs(array2[i]) + : 0.0); + } +#else + if (abs(array1(i)) > abs(array2(i))) { + max_relative_error_norm = (abs(array1(i)) > 1e-20 + ? max_absolute_error_norm / abs(array1(i)) + : 0.0); + } + else { + max_relative_error_norm = (abs(array2(i)) > 1e-20 + ? max_absolute_error_norm / abs(array2(i)) + : 0.0); + } +#endif + } + } +} + +template +void getMaxAbsoluteAndRelativeErrorNorms(const TArray2D & array1, + const TComplexArray2D & array2, + const size_t size1, const size_t size2, + real_type & max_absolute_error_norm, + real_type & max_relative_error_norm) +{ + using std::abs; + + real_type current_error; + + // NOTE: no parallelization here, it is a completely sequential loop! + for(int i = 0; i < static_cast(size1); ++i) { + for(int j = 0; j < static_cast(size2); ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + current_error = abs(array1[i][j] - array2[i][j]); +#else + current_error = abs(array1(i,j) - array2(i,j)); +#endif + if (current_error > max_absolute_error_norm) { + max_absolute_error_norm = current_error; +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + if (abs(array1[i][j]) > abs(array2[i][j])) { + max_relative_error_norm = (abs(array1[i][j]) > 1e-20 + ? max_absolute_error_norm / abs(array1[i][j]) + : 0.0); + } + else { + max_relative_error_norm = (abs(array2[i][j]) > 1e-20 + ? max_absolute_error_norm / abs(array2[i][j]) + : 0.0); + } +#else + if (abs(array1(i,j)) > abs(array2(i,j))) { + max_relative_error_norm = (abs(array1(i,j)) > 1e-20 + ? max_absolute_error_norm / abs(array1(i,j)) + : 0.0); + } + else { + max_relative_error_norm = (abs(array2(i,j)) > 1e-20 + ? max_absolute_error_norm / abs(array2(i,j)) + : 0.0); + } +#endif + } + } + } +} + +template +void getMaxAbsoluteAndRelativeErrorNorms(const TArray3D & array1, const TComplexArray3D & array2, + const size_t size1, const size_t size2, + const size_t size3, real_type & max_absolute_error_norm, + real_type & max_relative_error_norm) +{ + using std::abs; + + real_type current_error; + + // NOTE: no parallelization here, it is a completely sequential loop! + for(int i = 0; i < static_cast(size1); ++i) { + for(int j = 0; j < static_cast(size2); ++j) { + for(int k = 0; k < static_cast(size3); ++k) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + current_error = abs(array1[i][j][k] - array2[i][j][k]); +#else + current_error = abs(array1(i,j,k) - array2(i,j,k)); +#endif + if (current_error > max_absolute_error_norm) { + max_absolute_error_norm = current_error; +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + if (abs(array1[i][j][k]) > abs(array2[i][j][k])) { + max_relative_error_norm = (abs(array1[i][j][k]) > 1e-20 + ? max_absolute_error_norm / abs(array1[i][j][k]) + : 0.0); + } + else { + max_relative_error_norm = (abs(array2[i][j][k]) > 1e-20 + ? max_absolute_error_norm / abs(array2[i][j][k]) + : 0.0); + } +#else + if (abs(array1(i,j,k)) > abs(array2(i,j,k))) { + max_relative_error_norm = (abs(array1(i,j,k)) > 1e-20 + ? max_absolute_error_norm / abs(array1(i,j,k)) + : 0.0); + } + else { + max_relative_error_norm = (abs(array2(i,j,k)) > 1e-20 + ? max_absolute_error_norm / abs(array2(i,j,k)) + : 0.0); + } +#endif + } + } + } + } +} + +template +real_type squareAbsAccumulate(const TArray1D & array, const size_t size, + const real_type init) +{ + int size_signed = static_cast(size); + real_type sum = init; + + using std::abs; + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for reduction(+:sum) +#endif +#endif + for(int i = 0; i < size_signed; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + sum += abs(array[i] * array[i]); +#else + sum += abs(array(i) * array(i)); +#endif + } + + return sum; +} + +template +real_type squareAbsAccumulate(const TArray2D & array, const size_t size1, + const size_t size2, const real_type init) +{ + int size1_signed = static_cast(size1); + int size2_signed = static_cast(size2); + real_type sum = init; + + using std::abs; + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for reduction(+:sum) +#endif +#endif + for(int i = 0; i < size1_signed; ++i) { + for(int j = 0; j < size2_signed; ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + sum += abs(array[i][j] * array[i][j]); +#else + sum += abs(array(i,j) * array(i,j)); +#endif + } + } + + return sum; +} + +template +real_type squareAbsAccumulate(const TArray3D & array, const size_t size1, + const size_t size2, const size_t size3, + const real_type init) +{ + int size1_signed = static_cast(size1); + int size2_signed = static_cast(size2); + int size3_signed = static_cast(size3); + real_type sum = init; + + using std::abs; + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for reduction(+:sum) +#endif +#endif + for(int i = 0; i < size1_signed; ++i) { + for(int j = 0; j < size2_signed; ++j) { + for(int k = 0; k < size3_signed; ++k) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + sum += abs(array[i][j][k] * array[i][j][k]); +#else + sum += abs(array(i,j,k) * array(i,j,k)); +#endif + } + } + } + + return sum; +} + +// Generic template for CCheckFFT struct followed by its explicit specializations +// for certain numbers of dimensions. TArray can be either of real or complex type. +// The technique is similar to the one applied for CFFT struct. +template +struct CCheckFFT +{}; + +template +struct CCheckFFT +{ + static bool check_fft(const TArray1D & data_before, + const TComplexArray1D & data_after, + const size_t size, const real_type relative_tolerance, + real_type & discrepancy, const CheckMode check_mode, + const char *& error_description) + { + using namespace error_handling; + + if(0 == size) { + GetErrorDescription(EC_NUM_OF_ELEMS_IS_ZERO, error_description); + return false; + } + + if ( (CHECK_FFT_PARSEVAL != check_mode) && + (CHECK_FFT_ENERGY != check_mode) && + (CHECK_FFT_EQUALITY != check_mode) ) + { + GetErrorDescription(EC_WRONG_CHECK_FFT_MODE, error_description); + return false; + } + + if (CHECK_FFT_EQUALITY != check_mode) + { + real_type sum_before = squareAbsAccumulate(data_before, size, 0.0); + real_type sum_after = squareAbsAccumulate(data_after, size, 0.0); + + if (CHECK_FFT_PARSEVAL == check_mode) { + sum_after /= size; + } + + using std::abs; + + discrepancy = abs(sum_before - sum_after); + + if (discrepancy / ((sum_before < 1e-20) ? (sum_before + 1e-20) : sum_before) > relative_tolerance) { + GetErrorDescription(EC_RELATIVE_ERROR_TOO_LARGE, error_description); + return false; + } + else { + return true; + } + } + else { + real_type relative_error; + getMaxAbsoluteAndRelativeErrorNorms(data_before, data_after, size, + discrepancy, relative_error); + if (relative_error < relative_tolerance) { + return true; + } + else { + GetErrorDescription(EC_RELATIVE_ERROR_TOO_LARGE, error_description); + return false; + } + } + } +}; + +template +struct CCheckFFT +{ + static bool check_fft(const TArray2D & data_before, + const TComplexArray2D & data_after, + const size_t size1, const size_t size2, + const real_type relative_tolerance, real_type & discrepancy, + const CheckMode check_mode, const char *& error_description) + { + using namespace error_handling; + + if( (0 == size1) || (0 == size2) ) { + GetErrorDescription(EC_NUM_OF_ELEMS_IS_ZERO, error_description); + return false; + } + + if ( (CHECK_FFT_PARSEVAL != check_mode) && + (CHECK_FFT_ENERGY != check_mode) && + (CHECK_FFT_EQUALITY != check_mode) ) + { + GetErrorDescription(EC_WRONG_CHECK_FFT_MODE, error_description); + return false; + } + + if (CHECK_FFT_EQUALITY != check_mode) + { + real_type sum_before = squareAbsAccumulate(data_before, size1, size2, 0.0); + real_type sum_after = squareAbsAccumulate(data_after, size1, size2, 0.0); + + if (CHECK_FFT_PARSEVAL == check_mode) { + sum_after /= size1 * size2; + } + + using std::abs; + + discrepancy = abs(sum_before - sum_after); + + if (discrepancy / ((sum_before < 1e-20) ? (sum_before + 1e-20) : sum_before) > relative_tolerance) { + GetErrorDescription(EC_RELATIVE_ERROR_TOO_LARGE, error_description); + return false; + } + else { + return true; + } + } + else { + real_type relative_error; + getMaxAbsoluteAndRelativeErrorNorms(data_before, data_after, size1, + size2, discrepancy, relative_error); + if (relative_error < relative_tolerance) { + return true; + } + else { + GetErrorDescription(EC_RELATIVE_ERROR_TOO_LARGE, error_description); + return false; + } + } + } +}; + +template +struct CCheckFFT +{ + static bool check_fft(const TArray3D & data_before, + const TComplexArray3D & data_after, + const size_t size1, const size_t size2, const size_t size3, + const real_type relative_tolerance, real_type & discrepancy, + const CheckMode check_mode, const char *& error_description) + { + using namespace error_handling; + + if( (0 == size1) || (0 == size2) || (0 == size3) ) { + GetErrorDescription(EC_NUM_OF_ELEMS_IS_ZERO, error_description); + return false; + } + + if ( (CHECK_FFT_PARSEVAL != check_mode) && + (CHECK_FFT_ENERGY != check_mode) && + (CHECK_FFT_EQUALITY != check_mode) ) + { + GetErrorDescription(EC_WRONG_CHECK_FFT_MODE, error_description); + return false; + } + + if (CHECK_FFT_EQUALITY != check_mode) + { + real_type sum_before = squareAbsAccumulate(data_before, size1, size2, size3, 0.0); + real_type sum_after = squareAbsAccumulate(data_after, size1, size2, size3, 0.0); + + if (CHECK_FFT_PARSEVAL == check_mode) { + sum_after /= size1 * size2 * size3; + } + + using std::abs; + + discrepancy = abs(sum_before - sum_after); + + if (discrepancy / ((sum_before < 1e-20) ? (sum_before + 1e-20) : sum_before) > relative_tolerance) { + GetErrorDescription(EC_RELATIVE_ERROR_TOO_LARGE, error_description); + return false; + } + else { + return true; + } + } + else { + real_type relative_error; + getMaxAbsoluteAndRelativeErrorNorms(data_before, data_after, size1, + size2, size3, discrepancy, relative_error); + if (relative_error < relative_tolerance) { + return true; + } + else { + GetErrorDescription(EC_RELATIVE_ERROR_TOO_LARGE, error_description); + return false; + } + } + } +}; + +} // namespace check_fft_private + +namespace check_fft { + +template +bool checkParsevalTheorem(const TArray1D & data_before_FFT, + const TComplexArray1D & data_after_FFT, + const size_t size, const real_type relative_tolerance, + real_type & discrepancy, const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT, size, relative_tolerance, + discrepancy, check_fft_private::CHECK_FFT_PARSEVAL, + error_description); +} + +template +bool checkParsevalTheorem(const TArray2D & data_before_FFT, + const TComplexArray2D & data_after_FFT, + const size_t size1, const size_t size2, + const real_type relative_tolerance, + real_type & discrepancy, const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT, size1, size2, relative_tolerance, + discrepancy, check_fft_private::CHECK_FFT_PARSEVAL, + error_description); +} + +template +bool checkParsevalTheorem(const TArray3D & data_before_FFT, + const TComplexArray3D & data_after_FFT, + const size_t size1, const size_t size2, const size_t size3, + const real_type relative_tolerance, real_type & discrepancy, + const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT, size1, size2, size3, + relative_tolerance, discrepancy, + check_fft_private::CHECK_FFT_PARSEVAL, + error_description); +} + +template +bool checkEnergyConservation(const TArray1D & data_before_FFT, + const TComplexArray1D & data_after_FFT_and_IFFT, + const size_t size, const real_type relative_tolerance, + real_type & discrepancy, const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT_and_IFFT, size, relative_tolerance, + discrepancy, check_fft_private::CHECK_FFT_ENERGY, + error_description); +} + +template +bool checkEnergyConservation(const TArray2D & data_before_FFT, + const TComplexArray2D & data_after_FFT_and_IFFT, + const size_t size1, const size_t size2, + const real_type relative_tolerance, + real_type & discrepancy, const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT_and_IFFT, size1, size2, + relative_tolerance, discrepancy, + check_fft_private::CHECK_FFT_ENERGY, + error_description); +} + +template +bool checkEnergyConservation(const TArray3D & data_before_FFT, + const TComplexArray3D & data_after_FFT_and_IFFT, + const size_t size1, const size_t size2, const size_t size3, + const real_type relative_tolerance, real_type & discrepancy, + const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT_and_IFFT, size1, size2, + size3, relative_tolerance, discrepancy, + check_fft_private::CHECK_FFT_ENERGY, + error_description); +} + +template +bool checkEquality(const TArray1D & data_before_FFT, + const TComplexArray1D & data_after_FFT_and_IFFT, + const size_t size, const real_type relative_tolerance, + real_type & discrepancy, const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT_and_IFFT, size, relative_tolerance, + discrepancy, check_fft_private::CHECK_FFT_EQUALITY, + error_description); +} + +template +bool checkEquality(const TArray2D & data_before_FFT, + const TComplexArray2D & data_after_FFT_and_IFFT, const size_t size1, + const size_t size2, const real_type relative_tolerance, + real_type & discrepancy, const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT_and_IFFT, size1, size2, + relative_tolerance, discrepancy, + check_fft_private::CHECK_FFT_EQUALITY, + error_description); +} + +template +bool checkEquality(const TArray3D & data_before_FFT, + const TComplexArray3D & data_after_FFT_and_IFFT, const size_t size1, + const size_t size2, const size_t size3, const real_type relative_tolerance, + real_type & discrepancy, const char *& error_description) +{ + return check_fft_private::CCheckFFT::check_fft(data_before_FFT, + data_after_FFT_and_IFFT, size1, size2, + size3, relative_tolerance, discrepancy, + check_fft_private::CHECK_FFT_EQUALITY, + error_description); +} + +} // namespace check_fft +} // namespace simple_fft + +#endif // __SIMPLE_FFT__CHECK_FFT_HPP__ diff --git a/debian/missing-sources/Simple-FFT/include/simple_fft/copy_array.hpp b/debian/missing-sources/Simple-FFT/include/simple_fft/copy_array.hpp new file mode 100644 index 0000000..bb4c076 --- /dev/null +++ b/debian/missing-sources/Simple-FFT/include/simple_fft/copy_array.hpp @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2013-2020 Dmitry Ivanov + * + * This file is a part of Simple-FFT project and is distributed under the terms + * of MIT license: https://opensource.org/licenses/MIT + */ + +#ifndef __SIMPLE_FFT__COPY_ARRAY_HPP +#define __SIMPLE_FFT__COPY_ARRAY_HPP + +#include "fft_settings.h" +#include "error_handling.hpp" +#include + +using std::size_t; + +namespace simple_fft { +namespace copy_array { + +template +void copyArray(const TComplexArray1D & data_from, TComplexArray1D & data_to, + const size_t size) +{ + int size_signed = static_cast(size); + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < size_signed; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data_to[i] = data_from[i]; +#else + data_to(i) = data_from(i); +#endif + } +} + +template +void copyArray(const TRealArray1D & data_from, TComplexArray1D & data_to, + const size_t size) +{ + int size_signed = static_cast(size); + + // NOTE: user's complex type should have constructor like + // "complex(real, imag)", where each of real and imag has + // real type. + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < size_signed; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data_to[i] = complex_type(data_from[i], 0.0); +#else + data_to(i) = complex_type(data_from(i), 0.0); +#endif + } +} + +template +void copyArray(const TComplexArray2D & data_from, TComplexArray2D & data_to, + const size_t size1, const size_t size2) +{ + int size1_signed = static_cast(size1); + int size2_signed = static_cast(size2); + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < size1_signed; ++i) { + for(int j = 0; j < size2_signed; ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data_to[i][j] = data_from[i][j]; +#else + data_to(i,j) = data_from(i,j); +#endif + } + } +} + +template +void copyArray(const TRealArray2D & data_from, TComplexArray2D & data_to, + const size_t size1, const size_t size2) +{ + int size1_signed = static_cast(size1); + int size2_signed = static_cast(size2); + + // NOTE: user's complex type should have constructor like + // "complex(real, imag)", where each of real and imag has + // real type. + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < size1_signed; ++i) { + for(int j = 0; j < size2_signed; ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data_to[i][j] = complex_type(data_from[i][j], 0.0); +#else + data_to(i,j) = complex_type(data_from(i,j), 0.0); +#endif + } + } +} + +template +void copyArray(const TComplexArray3D & data_from, TComplexArray3D & data_to, + const size_t size1, const size_t size2, const size_t size3) +{ + int size1_signed = static_cast(size1); + int size2_signed = static_cast(size2); + int size3_signed = static_cast(size3); + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < size1_signed; ++i) { + for(int j = 0; j < size2_signed; ++j) { + for(int k = 0; k < size3_signed; ++k) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data_to[i][j][k] = data_from[i][j][k]; +#else + data_to(i,j,k) = data_from(i,j,k); +#endif + } + } + } +} + +template +void copyArray(const TRealArray3D & data_from, TComplexArray3D & data_to, + const size_t size1, const size_t size2, const size_t size3) +{ + int size1_signed = static_cast(size1); + int size2_signed = static_cast(size2); + int size3_signed = static_cast(size3); + + // NOTE: user's complex type should have constructor like + // "complex(real, imag)", where each of real and imag has + // real type. + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < size1_signed; ++i) { + for(int j = 0; j < size2_signed; ++j) { + for(int k = 0; k < size3_signed; ++k) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data_to[i][j][k] = complex_type(data_from[i][j][k], 0.0); +#else + data_to(i,j,k) = complex_type(data_from(i,j,k), 0.0); +#endif + } + } + } +} + +} // namespace copy_array +} // namespace simple_fft + +#endif // __SIMPLE_FFT__COPY_ARRAY_HPP diff --git a/debian/missing-sources/Simple-FFT/include/simple_fft/error_handling.hpp b/debian/missing-sources/Simple-FFT/include/simple_fft/error_handling.hpp new file mode 100644 index 0000000..608ecc9 --- /dev/null +++ b/debian/missing-sources/Simple-FFT/include/simple_fft/error_handling.hpp @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2013-2020 Dmitry Ivanov + * + * This file is a part of Simple-FFT project and is distributed under the terms + * of MIT license: https://opensource.org/licenses/MIT + */ + +#ifndef __SIMPLE_FFT__ERROR_HANDLING_HPP +#define __SIMPLE_FFT__ERROR_HANDLING_HPP + +namespace simple_fft { +namespace error_handling { + +enum EC_SimpleFFT +{ + EC_SUCCESS = 0, + EC_UNSUPPORTED_DIMENSIONALITY, + EC_WRONG_FFT_DIRECTION, + EC_ONE_OF_DIMS_ISNT_POWER_OF_TWO, + EC_NUM_OF_ELEMS_IS_ZERO, + EC_WRONG_CHECK_FFT_MODE, + EC_RELATIVE_ERROR_TOO_LARGE +}; + +inline void GetErrorDescription(const EC_SimpleFFT error_code, + const char *& error_description) +{ + switch(error_code) + { + case EC_SUCCESS: + error_description = "Calculation was successful!"; + break; + case EC_UNSUPPORTED_DIMENSIONALITY: + error_description = "Unsupported dimensionality: currently only 1D, 2D " + "and 3D arrays are supported"; + break; + case EC_WRONG_FFT_DIRECTION: + error_description = "Wrong direction for FFT was specified"; + break; + case EC_ONE_OF_DIMS_ISNT_POWER_OF_TWO: + error_description = "Unsupported dimensionality: one of dimensions is not " + "a power of 2"; + break; + case EC_NUM_OF_ELEMS_IS_ZERO: + error_description = "Number of elements for FFT or IFFT is zero!"; + break; + case EC_WRONG_CHECK_FFT_MODE: + error_description = "Wrong check FFT mode was specified (should be either " + "Parseval theorem or energy conservation check"; + break; + case EC_RELATIVE_ERROR_TOO_LARGE: + error_description = "Relative error returned by FFT test exceeds specified " + "relative tolerance"; + break; + default: + error_description = "Unknown error"; + break; + } +} + +} // namespace error_handling +} // namespace simple_fft + +#endif // __SIMPLE_FFT__ERROR_HANDLING_HPP diff --git a/debian/missing-sources/Simple-FFT/include/simple_fft/fft.h b/debian/missing-sources/Simple-FFT/include/simple_fft/fft.h new file mode 100644 index 0000000..3cf77f8 --- /dev/null +++ b/debian/missing-sources/Simple-FFT/include/simple_fft/fft.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2013-2020 Dmitry Ivanov + * + * This file is a part of Simple-FFT project and is distributed under the terms + * of MIT license: https://opensource.org/licenses/MIT + */ + +#ifndef __SIMPLE_FFT__FFT_H__ +#define __SIMPLE_FFT__FFT_H__ + +#include + +using std::size_t; + +/// The public API +namespace simple_fft { + +/// FFT and IFFT functions + +// in-place, complex, forward +template +bool FFT(TComplexArray1D & data, const size_t size, const char *& error_description); + +template +bool FFT(TComplexArray2D & data, const size_t size1, const size_t size2, + const char *& error_description); + +template +bool FFT(TComplexArray3D & data, const size_t size1, const size_t size2, const size_t size3, + const char *& error_description); + +// in-place, complex, inverse +template +bool IFFT(TComplexArray1D & data, const size_t size, const char *& error_description); + +template +bool IFFT(TComplexArray2D & data, const size_t size1, const size_t size2, + const char *& error_description); + +template +bool IFFT(TComplexArray3D & data, const size_t size1, const size_t size2, const size_t size3, + const char *& error_description); + +// not-in-place, complex, forward +template +bool FFT(const TComplexArray1D & data_in, TComplexArray1D & data_out, + const size_t size, const char *& error_description); + +template +bool FFT(const TComplexArray2D & data_in, TComplexArray2D & data_out, + const size_t size1, const size_t size2, const char *& error_description); + +template +bool FFT(const TComplexArray3D & data_in, TComplexArray3D & data_out, + const size_t size1, const size_t size2, const size_t size3, + const char *& error_description); + +// not-in-place, complex, inverse +template +bool IFFT(const TComplexArray1D & data_in, TComplexArray1D & data_out, + const size_t size, const char *& error_description); + +template +bool IFFT(const TComplexArray2D & data_in, TComplexArray2D & data_out, + const size_t size1, const size_t size2, const char *& error_description); + +template +bool IFFT(const TComplexArray3D & data_in, TComplexArray3D & data_out, + const size_t size1, const size_t size2, const size_t size3, + const char *& error_description); + +// not-in-place, real, forward +template +bool FFT(const TRealArray1D & data_in, TComplexArray1D & data_out, + const size_t size, const char *& error_description); + +template +bool FFT(const TRealArray2D & data_in, TComplexArray2D & data_out, + const size_t size1, const size_t size2, const char *& error_description); + +template +bool FFT(const TRealArray3D & data_in, TComplexArray3D & data_out, + const size_t size1, const size_t size2, const size_t size3, + const char *& error_description); + +// NOTE: There is no inverse transform from complex spectrum to real signal +// because round-off errors during computation of inverse FFT lead to the appearance +// of signal imaginary components even though they are small by absolute value. +// These can be ignored but the author of this file thinks adding such an function +// would be wrong methodogically: looking at complex result, you can estimate +// the value of spurious imaginary part. Otherwise you may never know that IFFT +// provides too large imaginary values due to too small grid size, for example. + +} // namespace simple_fft + +#endif // __SIMPLE_FFT__FFT_H__ + +#include "fft.hpp" diff --git a/debian/missing-sources/Simple-FFT/include/simple_fft/fft.hpp b/debian/missing-sources/Simple-FFT/include/simple_fft/fft.hpp new file mode 100644 index 0000000..dca498d --- /dev/null +++ b/debian/missing-sources/Simple-FFT/include/simple_fft/fft.hpp @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2013-2020 Dmitry Ivanov + * + * This file is a part of Simple-FFT project and is distributed under the terms + * of MIT license: https://opensource.org/licenses/MIT + */ + +#ifndef __SIMPLE_FFT__FFT_HPP__ +#define __SIMPLE_FFT__FFT_HPP__ + +#include "copy_array.hpp" +#include "fft_impl.hpp" + +namespace simple_fft { + +// in-place, complex, forward +template +bool FFT(TComplexArray1D & data, const size_t size, const char *& error_description) +{ + return impl::CFFT::FFT_inplace(data, size, impl::FFT_FORWARD, + error_description); +} + +template +bool FFT(TComplexArray2D & data, const size_t size1, const size_t size2, + const char *& error_description) +{ + return impl::CFFT::FFT_inplace(data, size1, size2, impl::FFT_FORWARD, + error_description); +} + +template +bool FFT(TComplexArray3D & data, const size_t size1, const size_t size2, const size_t size3, + const char *& error_description) +{ + return impl::CFFT::FFT_inplace(data, size1, size2, size3, + impl::FFT_FORWARD, + error_description); +} + +// in-place, complex, inverse +template +bool IFFT(TComplexArray1D & data, const size_t size, const char *& error_description) +{ + return impl::CFFT::FFT_inplace(data, size, impl::FFT_BACKWARD, + error_description); +} + +template +bool IFFT(TComplexArray2D & data, const size_t size1, const size_t size2, + const char *& error_description) +{ + return impl::CFFT::FFT_inplace(data, size1, size2, impl::FFT_BACKWARD, + error_description); +} + +template +bool IFFT(TComplexArray3D & data, const size_t size1, const size_t size2, const size_t size3, + const char *& error_description) +{ + return impl::CFFT::FFT_inplace(data, size1, size2, size3, + impl::FFT_BACKWARD, + error_description); +} + +// not-in-place, complex, forward +template +bool FFT(const TComplexArray1D & data_in, TComplexArray1D & data_out, + const size_t size, const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size); + return impl::CFFT::FFT_inplace(data_out, size, impl::FFT_FORWARD, + error_description); +} + +template +bool FFT(const TComplexArray2D & data_in, TComplexArray2D & data_out, + const size_t size1, const size_t size2, const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size1, size2); + return impl::CFFT::FFT_inplace(data_out, size1, size2, + impl::FFT_FORWARD, + error_description); +} + +template +bool FFT(const TComplexArray3D & data_in, TComplexArray3D & data_out, + const size_t size1, const size_t size2, const size_t size3, + const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size1, size2, size3); + return impl::CFFT::FFT_inplace(data_out, size1, size2, size3, + impl::FFT_FORWARD, + error_description); +} + +// not-in-place, complex, inverse +template +bool IFFT(const TComplexArray1D & data_in, TComplexArray1D & data_out, + const size_t size, const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size); + return impl::CFFT::FFT_inplace(data_out, size, impl::FFT_BACKWARD, + error_description); +} + +template +bool IFFT(const TComplexArray2D & data_in, TComplexArray2D & data_out, + const size_t size1, const size_t size2, const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size1, size2); + return impl::CFFT::FFT_inplace(data_out, size1, size2, + impl::FFT_BACKWARD, + error_description); +} + +template +bool IFFT(const TComplexArray3D & data_in, TComplexArray3D & data_out, + const size_t size1, const size_t size2, const size_t size3, + const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size1, size2, size3); + return impl::CFFT::FFT_inplace(data_out, size1, size2, size3, + impl::FFT_BACKWARD, + error_description); +} + +// not-in-place, real, forward +template +bool FFT(const TRealArray1D & data_in, TComplexArray1D & data_out, + const size_t size, const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size); + return impl::CFFT::FFT_inplace(data_out, size, + impl::FFT_FORWARD, + error_description); +} + +template +bool FFT(const TRealArray2D & data_in, TComplexArray2D & data_out, + const size_t size1, const size_t size2, const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size1, size2); + return impl::CFFT::FFT_inplace(data_out, size1, size2, + impl::FFT_FORWARD, + error_description); +} + +template +bool FFT(const TRealArray3D & data_in, TComplexArray3D & data_out, + const size_t size1, const size_t size2, const size_t size3, + const char *& error_description) +{ + copy_array::copyArray(data_in, data_out, size1, size2, size3); + return impl::CFFT::FFT_inplace(data_out, size1, size2, size3, + impl::FFT_FORWARD, + error_description); +} + +} // simple_fft + +#endif // __SIMPLE_FFT__FFT_HPP__ diff --git a/debian/missing-sources/Simple-FFT/include/simple_fft/fft_impl.hpp b/debian/missing-sources/Simple-FFT/include/simple_fft/fft_impl.hpp new file mode 100644 index 0000000..b385f07 --- /dev/null +++ b/debian/missing-sources/Simple-FFT/include/simple_fft/fft_impl.hpp @@ -0,0 +1,515 @@ +/** + * Copyright (c) 2013-2020 Dmitry Ivanov + * + * This file is a part of Simple-FFT project and is distributed under the terms + * of MIT license: https://opensource.org/licenses/MIT + */ + +#ifndef __SIMPLE_FFT__FFT_IMPL_HPP__ +#define __SIMPLE_FFT__FFT_IMPL_HPP__ + +#include "fft_settings.h" +#include "error_handling.hpp" +#include +#include +#include + +using std::size_t; + +#ifndef M_PI +#define M_PI 3.1415926535897932 +#endif + +namespace simple_fft { +namespace impl { + +enum FFT_direction +{ + FFT_FORWARD = 0, + FFT_BACKWARD +}; + +// checking whether the size of array dimension is power of 2 +// via "complement and compare" method +inline bool isPowerOfTwo(const size_t num) +{ + return num && (!(num & (num - 1))); +} + +inline bool checkNumElements(const size_t num_elements, const char *& error_description) +{ + using namespace error_handling; + + if (!isPowerOfTwo(num_elements)) { + GetErrorDescription(EC_ONE_OF_DIMS_ISNT_POWER_OF_TWO, error_description); + return false; + } + + return true; +} + +template +inline void scaleValues(TComplexArray1D & data, const size_t num_elements) +{ + real_type mult = 1.0 / num_elements; + int num_elements_signed = static_cast(num_elements); + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < num_elements_signed; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data[i] *= mult; +#else + data(i) *= mult; +#endif + } +} + +// NOTE: explicit template specialization for the case of std::vector +// because it is used in 2D and 3D FFT for both array classes with square and round +// brackets of element access operator; I need to guarantee that sub-FFT 1D will +// use square brackets for element access operator anyway. It is pretty ugly +// to duplicate the code but I haven't found more elegant solution. +template <> +inline void scaleValues >(std::vector & data, + const size_t num_elements) +{ + real_type mult = 1.0 / num_elements; + int num_elements_signed = static_cast(num_elements); + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < num_elements_signed; ++i) { + data[i] *= mult; + } +} + +template +inline void bufferExchangeHelper(TComplexArray1D & data, const size_t index_from, + const size_t index_to, complex_type & buf) +{ +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + buf = data[index_from]; + data[index_from] = data[index_to]; + data[index_to]= buf; +#else + buf = data(index_from); + data(index_from) = data(index_to); + data(index_to)= buf; +#endif +} + +// NOTE: explicit template specialization for the case of std::vector +// because it is used in 2D and 3D FFT for both array classes with square and round +// brackets of element access operator; I need to guarantee that sub-FFT 1D will +// use square brackets for element access operator anyway. It is pretty ugly +// to duplicate the code but I haven't found more elegant solution. +template <> +inline void bufferExchangeHelper >(std::vector & data, + const size_t index_from, + const size_t index_to, + complex_type & buf) +{ + buf = data[index_from]; + data[index_from] = data[index_to]; + data[index_to]= buf; +} + +template +void rearrangeData(TComplexArray1D & data, const size_t num_elements) +{ + complex_type buf; + + size_t target_index = 0; + size_t bit_mask; + + for (size_t i = 0; i < num_elements; ++i) + { + if (target_index > i) + { + bufferExchangeHelper(data, target_index, i, buf); + } + + // Initialize the bit mask + bit_mask = num_elements; + + // While bit is 1 + while (target_index & (bit_mask >>= 1)) // bit_mask = bit_mask >> 1 + { + // Drop bit: + // & is bitwise AND, + // ~ is bitwise NOT + target_index &= ~bit_mask; // target_index = target_index & (~bit_mask) + } + + // | is bitwise OR + target_index |= bit_mask; // target_index = target_index | bit_mask + } +} + +template +inline void fftTransformHelper(TComplexArray1D & data, const size_t match, + const size_t k, complex_type & product, + const complex_type factor) +{ +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + product = data[match] * factor; + data[match] = data[k] - product; + data[k] += product; +#else + product = data(match) * factor; + data(match) = data(k) - product; + data(k) += product; +#endif +} + +// NOTE: explicit template specialization for the case of std::vector +// because it is used in 2D and 3D FFT for both array classes with square and round +// brackets of element access operator; I need to guarantee that sub-FFT 1D will +// use square brackets for element access operator anyway. It is pretty ugly +// to duplicate the code but I haven't found more elegant solution. +template <> +inline void fftTransformHelper >(std::vector & data, + const size_t match, + const size_t k, + complex_type & product, + const complex_type factor) +{ + product = data[match] * factor; + data[match] = data[k] - product; + data[k] += product; +} + +template +bool makeTransform(TComplexArray1D & data, const size_t num_elements, + const FFT_direction fft_direction, const char *& error_description) +{ + using namespace error_handling; + using std::sin; + + double local_pi; + switch(fft_direction) + { + case(FFT_FORWARD): + local_pi = -M_PI; + break; + case(FFT_BACKWARD): + local_pi = M_PI; + break; + default: + GetErrorDescription(EC_WRONG_FFT_DIRECTION, error_description); + return false; + } + + // declare variables to cycle the bits of initial signal + size_t next, match; + real_type sine; + real_type delta; + complex_type mult, factor, product; + + // NOTE: user's complex type should have constructor like + // "complex(real, imag)", where each of real and imag has + // real type. + + // cycle for all bit positions of initial signal + for (size_t i = 1; i < num_elements; i <<= 1) + { + next = i << 1; // getting the next bit + delta = local_pi / i; // angle increasing + sine = sin(0.5 * delta); // supplementary sin + // multiplier for trigonometric recurrence + mult = complex_type(-2.0 * sine * sine, sin(delta)); + factor = 1.0; // start transform factor + + for (size_t j = 0; j < i; ++j) // iterations through groups + // with different transform factors + { + for (size_t k = j; k < num_elements; k += next) // iterations through + // pairs within group + { + match = k + i; + fftTransformHelper(data, match, k, product, factor); + } + factor = mult * factor + factor; + } + } + + return true; +} + +// Generic template for complex FFT followed by its explicit specializations +template +struct CFFT +{}; + +// 1D FFT: +template +struct CFFT +{ + // NOTE: passing by pointer is needed to avoid using element access operator + static bool FFT_inplace(TComplexArray1D & data, const size_t size, + const FFT_direction fft_direction, + const char *& error_description) + { + if(!checkNumElements(size, error_description)) { + return false; + } + + rearrangeData(data, size); + + if(!makeTransform(data, size, fft_direction, error_description)) { + return false; + } + + if (FFT_BACKWARD == fft_direction) { + scaleValues(data, size); + } + + return true; + } +}; + +// 2D FFT +template +struct CFFT +{ + static bool FFT_inplace(TComplexArray2D & data, const size_t size1, const size_t size2, + const FFT_direction fft_direction, const char *& error_description) + { + int n_rows = static_cast(size1); + int n_cols = static_cast(size2); + + // fft for columns + std::vector subarray(n_rows); // each column has n_rows elements + + for(int j = 0; j < n_cols; ++j) + { +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < n_rows; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + subarray[i] = data[i][j]; +#else + subarray[i] = data(i,j); +#endif + } + + if(!CFFT,1>::FFT_inplace(subarray, size1, + fft_direction, + error_description)) + { + return false; + } + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < n_rows; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data[i][j] = subarray[i]; +#else + data(i,j) = subarray[i]; +#endif + } + } + + // fft for rows + subarray.resize(n_cols); // each row has n_cols elements + + for(int i = 0; i < n_rows; ++i) + { +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int j = 0; j < n_cols; ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + subarray[j] = data[i][j]; +#else + subarray[j] = data(i,j); +#endif + } + + if(!CFFT,1>::FFT_inplace(subarray, size2, + fft_direction, + error_description)) + { + return false; + } + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int j = 0; j < n_cols; ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data[i][j] = subarray[j]; +#else + data(i,j) = subarray[j]; +#endif + } + } + + return true; + } +}; + +// 3D FFT +template +struct CFFT +{ + static bool FFT_inplace(TComplexArray3D & data, const size_t size1, const size_t size2, + const size_t size3, const FFT_direction fft_direction, + const char *& error_description) + { + int n_rows = static_cast(size1); + int n_cols = static_cast(size2); + int n_depth = static_cast(size3); + + std::vector subarray(n_rows); // for fft for columns: each column has n_rows elements + + for(int k = 0; k < n_depth; ++k) // for all depth layers + { + // fft for columns + for(int j = 0; j < n_cols; ++j) + { +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < n_rows; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + subarray[i] = data[i][j][k]; +#else + subarray[i] = data(i,j,k); +#endif + } + + if(!CFFT,1>::FFT_inplace(subarray, size1, + fft_direction, + error_description)) + { + return false; + } + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int i = 0; i < n_rows; ++i) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data[i][j][k] = subarray[i]; +#else + data(i,j,k) = subarray[i]; +#endif + } + } + } + + subarray.resize(n_cols); // for fft for rows: each row has n_cols elements + + for(int k = 0; k < n_depth; ++k) // for all depth layers + { + // fft for rows + for(int i = 0; i < n_rows; ++i) + { +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int j = 0; j < n_cols; ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + subarray[j] = data[i][j][k]; +#else + subarray[j] = data(i,j,k); +#endif + } + + if(!CFFT,1>::FFT_inplace(subarray, size2, + fft_direction, + error_description)) + { + return false; + } + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int j = 0; j < n_cols; ++j) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data[i][j][k] = subarray[j]; +#else + data(i,j,k) = subarray[j]; +#endif + } + } + } + + // fft for depth + subarray.resize(n_depth); // each depth strip contains n_depth elements + + for(int i = 0; i < n_rows; ++i) // for all rows layers + { + for(int j = 0; j < n_cols; ++j) // for all cols layers + { +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int k = 0; k < n_depth; ++k) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + subarray[k] = data[i][j][k]; +#else + subarray[k] = data(i,j,k); +#endif + } + + if(!CFFT,1>::FFT_inplace(subarray, size3, + fft_direction, + error_description)) + { + return false; + } + +#ifndef __clang__ +#ifdef __USE_OPENMP +#pragma omp parallel for +#endif +#endif + for(int k = 0; k < n_depth; ++k) { +#ifdef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + data[i][j][k] = subarray[k]; +#else + data(i,j,k) = subarray[k]; +#endif + } + } + } + + return true; + } +}; + +} // namespace impl +} // namespace simple_fft + +#endif // __SIMPLE_FFT__FFT_IMPL_HPP__ diff --git a/debian/missing-sources/Simple-FFT/include/simple_fft/fft_settings.h b/debian/missing-sources/Simple-FFT/include/simple_fft/fft_settings.h new file mode 100644 index 0000000..7d97b7d --- /dev/null +++ b/debian/missing-sources/Simple-FFT/include/simple_fft/fft_settings.h @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2013-2020 Dmitry Ivanov + * + * This file is a part of Simple-FFT project and is distributed under the terms + * of MIT license: https://opensource.org/licenses/MIT + */ + +// In this file you can alter some settings of the library: +// 1) Specify the desired real and complex types by typedef'ing real_type and complex_type. +// By default real_type is double and complex_type is std::complex. +// 2) If the array class uses square brackets for element access operator, define +// the macro __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR + +#ifndef __SIMPLE_FFT__FFT_SETTINGS_H__ +#define __SIMPLE_FFT__FFT_SETTINGS_H__ + +#include + +typedef float real_type; +typedef std::complex complex_type; + +#ifndef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR +#define __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR +#endif + +#endif // __SIMPLE_FFT__FFT_SETTINGS_H__ diff --git a/debian/rules b/debian/rules index 949331e..49327c8 100755 --- a/debian/rules +++ b/debian/rules @@ -11,6 +11,7 @@ CONFIG_gui = -Dnogui=false -Drtaudio=enabled -Djack=enabled builddir=debian/build/flavor- +simple-fft-include=$(CURDIR)/externals/Simple-FFT/include/ export QT_SELECT=qt5 DEB_SRCDIR = . @@ -18,6 +19,13 @@ DEB_SRCDIR = . %: dh $@ --sourcedirectory=$(DEB_SRCDIR) --buildsystem=meson +execute_before_dh_auto_build: + cp -r $(CURDIR)/debian/missing-sources/Simple-FFT/include/ \ + $(simple-fft-include) + +execute_after_dh_auto_clean: + rm -rf $(simple-fft-include) + #.PHONY: $(patsubst %,configure_%,$(FLAVORS)) override_dh_auto_configure-arch: $(patsubst %,configure_%,$(FLAVORS)) configure_%: