Added the possibility to shift to different fft backend. Now set to fftw. Seems to work properly
This commit is contained in:
parent
86e7cbbbe9
commit
195319ab29
106
CMakeLists.txt
106
CMakeLists.txt
@ -23,17 +23,32 @@ add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25
|
|||||||
|
|
||||||
add_definitions(-D_REENTRANT)
|
add_definitions(-D_REENTRANT)
|
||||||
|
|
||||||
|
# ############### Choose an fft backend here
|
||||||
|
#set(LASP_FFT_BACKEND fftpack)
|
||||||
|
set(LASP_FFT_BACKEND "fftw")
|
||||||
|
|
||||||
|
if(LASP_FFT_BACKEND STREQUAL "fftw")
|
||||||
|
find_library(FFTW_LIBRARY NAMES fftw3 fftw)
|
||||||
|
set(FFTW_LIBRARIES "${FFTW_LIBRARY}")
|
||||||
|
set(LASP_FFT_LIBRARY "${FFTW_LIBRARIES}")
|
||||||
|
add_definitions(-DLASP_FFT_BACKEND_FFTW)
|
||||||
|
elseif(LASP_FFT_BACKEND STREQUAL "fftpack")
|
||||||
|
add_definitions(-DLASP_FFT_BACKEND_FFTPACK)
|
||||||
|
set(LASP_FFT_LIBRARY "fftpack")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if(LASP_FLOAT STREQUAL "double")
|
if(LASP_FLOAT STREQUAL "double")
|
||||||
add_definitions(-DLASP_FLOAT=64)
|
add_definitions(-DLASP_FLOAT=64)
|
||||||
add_definitions(-DLASP_DOUBLE_PRECISION)
|
add_definitions(-DLASP_DOUBLE_PRECISION)
|
||||||
else()
|
else()
|
||||||
add_definitions(-DLASP_FLOAT=32)
|
add_definitions(-DLASP_FLOAT=32)
|
||||||
|
add_definitions(-DLASP_SINGLE_PRECISION)
|
||||||
endif(LASP_FLOAT STREQUAL "double")
|
endif(LASP_FLOAT STREQUAL "double")
|
||||||
|
|
||||||
if(NOT DEFINED LASP_DEBUG)
|
if(NOT DEFINED LASP_DEBUG)
|
||||||
message(FATAL_ERROR "LASP_DEBUG flag not defined. Please set -DLASP_DEBUG=TRUE
|
message(FATAL_ERROR "LASP_DEBUG flag not defined. Please set -DLASP_DEBUG=TRUE
|
||||||
or -DLASP_DEBUG=FALSE")
|
or -DLASP_DEBUG=FALSE")
|
||||||
endif(NOT DEFINED LASP_DEBUG)
|
endif(NOT DEFINED LASP_DEBUG)
|
||||||
|
|
||||||
# ##################### END Cmake variables converted to a macro
|
# ##################### END Cmake variables converted to a macro
|
||||||
@ -41,63 +56,62 @@ set(Python_ADDITIONAL_VERSIONS "3")
|
|||||||
# #################### Setting definitions and debug-specific compilation flags
|
# #################### Setting definitions and debug-specific compilation flags
|
||||||
|
|
||||||
if(LASP_DEBUG)
|
if(LASP_DEBUG)
|
||||||
set(TRACERNAME LASPTracer)
|
set(TRACERNAME LASPTracer)
|
||||||
set(LASP_DEBUG_CYTHON=True)
|
set(LASP_DEBUG_CYTHON=True)
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
message("Building debug code")
|
message("Building debug code")
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
add_definitions(-DLASP_DEBUG=1)
|
add_definitions(-DLASP_DEBUG=1)
|
||||||
add_definitions(-DTRACERNAME=${TRACERNAME})
|
add_definitions(-DTRACERNAME=${TRACERNAME})
|
||||||
add_definitions(-DDEBUG)
|
add_definitions(-DDEBUG)
|
||||||
add_definitions(-DTRACER=1)
|
add_definitions(-DTRACER=1)
|
||||||
# This will produce html files
|
# This will produce html files
|
||||||
set(CYTHON_ANNOTATE ON)
|
set(CYTHON_ANNOTATE ON)
|
||||||
# Add the __FILENAME__ macro
|
# Add the __FILENAME__ macro
|
||||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")
|
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")
|
||||||
else()
|
else()
|
||||||
message("Building LASP for release")
|
message("Building LASP for release")
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
set(LASP_DEBUG_CYTHON=False)
|
set(LASP_DEBUG_CYTHON=False)
|
||||||
set(CYTHON_ANNOTATE OFF)
|
set(CYTHON_ANNOTATE OFF)
|
||||||
set(CYTHON_NO_DOCSTRINGS ON)
|
set(CYTHON_NO_DOCSTRINGS ON)
|
||||||
# Strip unnecessary symbols
|
# Strip unnecessary symbols
|
||||||
# set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--gc-sections")
|
# set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--gc-sections")
|
||||||
# set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--gc-sections")
|
# set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--gc-sections")
|
||||||
|
|
||||||
add_definitions(-DTRACER=0 -DNDEBUG)
|
add_definitions(-DTRACER=0 -DNDEBUG)
|
||||||
endif(LASP_DEBUG)
|
endif(LASP_DEBUG)
|
||||||
|
|
||||||
# The last argument here takes care of calling SIGABRT when an integer overflow
|
# The last argument here takes care of calling SIGABRT when an integer overflow
|
||||||
# occures.
|
# occures.
|
||||||
############################## General compilation flags (independent of debug mode, windows or linux)
|
############################## General compilation flags (independent of debug mode, windows or linux)
|
||||||
set(CYTHON_EXTRA_C_FLAGS "-Wno-sign-compare -Wno-cpp -Wno-implicit-fallthrough\
|
set(CYTHON_EXTRA_C_FLAGS "-Wno-sign-compare -Wno-cpp -Wno-implicit-fallthrough -Wno-incompatible-pointer-types -Wno-strict-aliasing")
|
||||||
-Wno-incompatible-pointer-types -Wno-strict-aliasing")
|
|
||||||
|
|
||||||
# General make flags
|
# General make flags
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -std=c11 -Wall -Wextra -Wno-type-limits \
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -std=c11 -Wall -Wextra -Wno-type-limits \
|
||||||
-Werror=implicit-function-declaration -Werror=incompatible-pointer-types \
|
-Werror=implicit-function-declaration -Werror=incompatible-pointer-types \
|
||||||
-Werror=return-type")
|
-Werror=return-type")
|
||||||
|
|
||||||
# Debug make flags
|
# Debug make flags
|
||||||
set(CMAKE_C_FLAGS_DEBUG "-g" )
|
set(CMAKE_C_FLAGS_DEBUG "-g" )
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -mfpmath=sse -march=x86-64 -mtune=native \
|
set(CMAKE_C_FLAGS_RELEASE "-O2 -mfpmath=sse -march=x86-64 -mtune=native \
|
||||||
-fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions")
|
-fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions")
|
||||||
|
|
||||||
# set(CMAKE_C_FLAGS_RELEASE "-O2 -march=native -mtune=native -fomit-frame-pointer")
|
# set(CMAKE_C_FLAGS_RELEASE "-O2 -march=native -mtune=native -fomit-frame-pointer")
|
||||||
|
|
||||||
if(LASP_USE_BLAS)
|
if(LASP_USE_BLAS)
|
||||||
add_definitions(-DLASP_USE_BLAS=1)
|
add_definitions(-DLASP_USE_BLAS=1)
|
||||||
else()
|
else()
|
||||||
add_definitions(-DLASP_USE_BLAS=0)
|
add_definitions(-DLASP_USE_BLAS=0)
|
||||||
endif(LASP_USE_BLAS)
|
endif(LASP_USE_BLAS)
|
||||||
|
|
||||||
# ############################# End compilation flags
|
# ############################# End compilation flags
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
set(win32 true)
|
set(win32 true)
|
||||||
else()
|
else()
|
||||||
set(win32 false)
|
set(win32 false)
|
||||||
endif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
endif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
|
|
||||||
find_package(PythonLibs REQUIRED )
|
find_package(PythonLibs REQUIRED )
|
||||||
@ -105,9 +119,9 @@ find_package(PythonInterp REQUIRED)
|
|||||||
|
|
||||||
add_subdirectory(fftpack)
|
add_subdirectory(fftpack)
|
||||||
include_directories(
|
include_directories(
|
||||||
fftpack
|
fftpack
|
||||||
lasp/c
|
lasp/c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(lasp)
|
add_subdirectory(lasp)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
@ -116,18 +130,18 @@ add_subdirectory(test)
|
|||||||
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
|
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
|
||||||
|
|
||||||
set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/*.py"
|
set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/*.py"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/lasp/*.py"
|
"${CMAKE_CURRENT_SOURCE_DIR}/lasp/*.py"
|
||||||
"wrappers"
|
"wrappers"
|
||||||
"lasp_rtaudio")
|
"lasp_rtaudio")
|
||||||
|
|
||||||
# )
|
# )
|
||||||
set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
|
set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
|
||||||
|
|
||||||
# configure_file(${SETUP_PY_IN} ${SETUP_PY})
|
# configure_file(${SETUP_PY_IN} ${SETUP_PY})
|
||||||
add_custom_command(OUTPUT ${OUTPUT}
|
add_custom_command(OUTPUT ${OUTPUT}
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build
|
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
|
COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
|
||||||
DEPENDS ${DEPS})
|
DEPENDS ${DEPS})
|
||||||
|
|
||||||
add_custom_target(target ALL DEPENDS ${OUTPUT})
|
add_custom_target(target ALL DEPENDS ${OUTPUT})
|
||||||
|
|
||||||
@ -135,7 +149,7 @@ if(DEFINED INSTALL_DEBUG)
|
|||||||
set(EXTRA_SETUP_ARG --user -e)
|
set(EXTRA_SETUP_ARG --user -e)
|
||||||
else()
|
else()
|
||||||
set(EXTRA_SETUP_ARG "")
|
set(EXTRA_SETUP_ARG "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install ${EXTRA_SETUP_ARG} .)")
|
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install ${EXTRA_SETUP_ARG} .)")
|
||||||
|
@ -25,4 +25,4 @@ add_library(lasp_lib
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(lasp_lib fftpack openblas)
|
target_link_libraries(lasp_lib ${LASP_FFT_LIBRARY} openblas)
|
||||||
|
@ -9,12 +9,24 @@
|
|||||||
#include "lasp_tracer.h"
|
#include "lasp_tracer.h"
|
||||||
#include "lasp_fft.h"
|
#include "lasp_fft.h"
|
||||||
#include "lasp_types.h"
|
#include "lasp_types.h"
|
||||||
#include "fftpack.h"
|
|
||||||
|
|
||||||
|
#ifdef LASP_FFT_BACKEND_FFTPACK
|
||||||
|
#include "fftpack.h"
|
||||||
typedef struct Fft_s {
|
typedef struct Fft_s {
|
||||||
us nfft;
|
us nfft;
|
||||||
vd fft_work;
|
vd fft_work; // Storage memory for fftpack
|
||||||
} Fft;
|
};
|
||||||
|
#elif defined LASP_FFT_BACKEND_FFTW
|
||||||
|
#include <fftw3.h>
|
||||||
|
typedef struct Fft_s {
|
||||||
|
us nfft;
|
||||||
|
fftw_plan forward_plan;
|
||||||
|
fftw_plan reverse_plan;
|
||||||
|
c* complex_storage;
|
||||||
|
d* real_storage;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Fft* Fft_create(const us nfft) {
|
Fft* Fft_create(const us nfft) {
|
||||||
fsTRACE(15);
|
fsTRACE(15);
|
||||||
@ -24,72 +36,103 @@ Fft* Fft_create(const us nfft) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Fft* fft = a_malloc(sizeof(Fft));
|
Fft* fft = a_malloc(sizeof(Fft));
|
||||||
if(fft==NULL) {
|
|
||||||
WARN("Fft allocation failed");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fft->nfft = nfft;
|
fft->nfft = nfft;
|
||||||
|
|
||||||
|
#ifdef LASP_FFT_BACKEND_FFTPACK
|
||||||
/* Initialize foreign fft lib */
|
/* Initialize foreign fft lib */
|
||||||
fft->fft_work = vd_alloc(2*nfft+15);
|
fft->fft_work = vd_alloc(2*nfft+15);
|
||||||
|
|
||||||
npy_rffti(nfft,getvdval(&fft->fft_work,0));
|
npy_rffti(nfft,getvdval(&fft->fft_work,0));
|
||||||
check_overflow_vx(fft->fft_work);
|
check_overflow_vx(fft->fft_work);
|
||||||
|
#elif defined LASP_FFT_BACKEND_FFTW
|
||||||
|
fft->complex_storage = fftw_malloc(sizeof(c) * (nfft/2 + 1));
|
||||||
|
fft->real_storage = fftw_malloc(sizeof(d) * nfft);
|
||||||
|
|
||||||
|
fft->forward_plan = fftw_plan_dft_r2c_1d(nfft,
|
||||||
|
fft->real_storage,
|
||||||
|
fft->complex_storage,
|
||||||
|
FFTW_MEASURE);
|
||||||
|
fft->reverse_plan = fftw_plan_dft_c2r_1d(nfft,
|
||||||
|
fft->complex_storage,
|
||||||
|
fft->real_storage,
|
||||||
|
FFTW_MEASURE);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* print_vd(&fft->fft_work); */
|
/* print_vd(&fft->fft_work); */
|
||||||
|
|
||||||
feTRACE(15);
|
feTRACE(15);
|
||||||
return fft;
|
return fft;
|
||||||
}
|
}
|
||||||
void Fft_free(Fft* fft) {
|
void Fft_free(Fft* fft) {
|
||||||
fsTRACE(15);
|
fsTRACE(15);
|
||||||
dbgassert(fft,NULLPTRDEREF);
|
dbgassert(fft,NULLPTRDEREF);
|
||||||
|
#ifdef LASP_FFT_BACKEND_FFTPACK
|
||||||
vd_free(&fft->fft_work);
|
vd_free(&fft->fft_work);
|
||||||
|
#elif defined LASP_FFT_BACKEND_FFTW
|
||||||
|
fftw_free(fft->complex_storage);
|
||||||
|
fftw_free(fft->real_storage);
|
||||||
|
fftw_destroy_plan(fft->forward_plan);
|
||||||
|
fftw_destroy_plan(fft->reverse_plan);
|
||||||
|
#endif
|
||||||
a_free(fft);
|
a_free(fft);
|
||||||
feTRACE(15);
|
feTRACE(15);
|
||||||
}
|
}
|
||||||
|
|
||||||
us Fft_nfft(const Fft* fft) {return fft->nfft;}
|
us Fft_nfft(const Fft* fft) {return fft->nfft;}
|
||||||
|
|
||||||
void Fft_ifft_single(const Fft* fft,const vc* freqdata,vd* result) {
|
void Fft_ifft_single(const Fft* fft,const vc* freqdata,vd* result) {
|
||||||
fsTRACE(15);
|
fsTRACE(15);
|
||||||
dbgassert(fft && freqdata && result,NULLPTRDEREF);
|
dbgassert(fft && freqdata && result,NULLPTRDEREF);
|
||||||
const us nfft = fft->nfft;
|
const us nfft = fft->nfft;
|
||||||
dbgassert(result->n_rows == nfft,
|
dbgassert(result->n_rows == nfft,
|
||||||
"Invalid size for time data rows."
|
"Invalid size for time data rows."
|
||||||
" Should be equal to nfft");
|
" Should be equal to nfft");
|
||||||
|
|
||||||
dbgassert(freqdata->n_rows == (nfft/2+1),"Invalid number of rows in"
|
dbgassert(freqdata->n_rows == (nfft/2+1),"Invalid number of rows in"
|
||||||
" result array");
|
" result array");
|
||||||
|
|
||||||
|
|
||||||
d* freqdata_ptr = (d*) getvcval(freqdata,0);
|
|
||||||
d* result_ptr = getvdval(result,0);
|
d* result_ptr = getvdval(result,0);
|
||||||
|
|
||||||
|
#ifdef LASP_FFT_BACKEND_FFTPACK
|
||||||
|
d* freqdata_ptr = (d*) getvcval(freqdata,0);
|
||||||
/* Copy freqdata, to fft_result. */
|
/* Copy freqdata, to fft_result. */
|
||||||
d_copy(&result_ptr[1],&freqdata_ptr[2],nfft-1,1,1);
|
d_copy(&result_ptr[1],&freqdata_ptr[2],nfft-1,1,1);
|
||||||
result_ptr[0] = freqdata_ptr[0];
|
result_ptr[0] = freqdata_ptr[0];
|
||||||
|
|
||||||
/* Perform inplace backward transform */
|
/* Perform inplace backward transform */
|
||||||
npy_rfftb(nfft,
|
npy_rfftb(nfft,
|
||||||
result_ptr,
|
result_ptr,
|
||||||
getvdval(&fft->fft_work,0));
|
getvdval(&fft->fft_work,0));
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined LASP_FFT_BACKEND_FFTW
|
||||||
|
c* freqdata_ptr = (c*) getvcval(freqdata,0);
|
||||||
|
|
||||||
|
c_copy(fft->complex_storage, freqdata_ptr,nfft/2+1);
|
||||||
|
|
||||||
|
fftw_execute(fft->reverse_plan);
|
||||||
|
|
||||||
|
d_copy(result_ptr, fft->real_storage, nfft, 1, 1);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
check_overflow_vx(*result);
|
||||||
|
|
||||||
/* Scale by dividing by nfft. Checked with numpy implementation
|
/* Scale by dividing by nfft. Checked with numpy implementation
|
||||||
* that this indeed needs to be done for FFTpack. */
|
* that this indeed needs to be done for FFTpack. */
|
||||||
d_scale(result_ptr,1/((d) nfft),nfft);
|
d_scale(result_ptr,1/((d) nfft),nfft);
|
||||||
|
|
||||||
check_overflow_vx(*result);
|
|
||||||
feTRACE(15);
|
feTRACE(15);
|
||||||
}
|
}
|
||||||
void Fft_ifft(const Fft* fft,const cmat* freqdata,dmat* timedata) {
|
void Fft_ifft(const Fft* fft,const cmat* freqdata,dmat* timedata) {
|
||||||
fsTRACE(15);
|
fsTRACE(15);
|
||||||
|
|
||||||
dbgassert(fft && timedata && freqdata,NULLPTRDEREF);
|
dbgassert(fft && timedata && freqdata,NULLPTRDEREF);
|
||||||
|
|
||||||
const us nchannels = timedata->n_cols;
|
const us nchannels = timedata->n_cols;
|
||||||
dbgassert(timedata->n_cols == freqdata->n_cols,
|
dbgassert(timedata->n_cols == freqdata->n_cols,
|
||||||
"Number of columns in timedata and result"
|
"Number of columns in timedata and result"
|
||||||
" should be equal.");
|
" should be equal.");
|
||||||
|
|
||||||
for(us col=0;col<nchannels;col++) {
|
for(us col=0;col<nchannels;col++) {
|
||||||
|
|
||||||
@ -108,7 +151,7 @@ void Fft_ifft(const Fft* fft,const cmat* freqdata,dmat* timedata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Fft_fft_single(const Fft* fft,const vd* timedata,vc* result) {
|
void Fft_fft_single(const Fft* fft,const vd* timedata,vc* result) {
|
||||||
|
|
||||||
fsTRACE(15);
|
fsTRACE(15);
|
||||||
dbgassert(fft && timedata && result,NULLPTRDEREF);
|
dbgassert(fft && timedata && result,NULLPTRDEREF);
|
||||||
|
|
||||||
@ -116,12 +159,14 @@ void Fft_fft_single(const Fft* fft,const vd* timedata,vc* result) {
|
|||||||
assert_vx(timedata);
|
assert_vx(timedata);
|
||||||
assert_vx(result);
|
assert_vx(result);
|
||||||
dbgassert(timedata->n_rows == nfft,
|
dbgassert(timedata->n_rows == nfft,
|
||||||
"Invalid size for time data rows."
|
"Invalid size for time data rows."
|
||||||
" Should be equal to nfft");
|
" Should be equal to nfft");
|
||||||
|
|
||||||
dbgassert(result->n_rows == (nfft/2+1),"Invalid number of rows in"
|
dbgassert(result->n_rows == (nfft/2+1),"Invalid number of rows in"
|
||||||
" result array");
|
" result array");
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LASP_FFT_BACKEND_FFTPACK
|
||||||
d* result_ptr = (d*) getvcval(result,0);
|
d* result_ptr = (d*) getvcval(result,0);
|
||||||
|
|
||||||
/* Fftpack stores the data a bit strange, the resulting array
|
/* Fftpack stores the data a bit strange, the resulting array
|
||||||
@ -136,35 +181,45 @@ void Fft_fft_single(const Fft* fft,const vd* timedata,vc* result) {
|
|||||||
|
|
||||||
/* Perform fft */
|
/* Perform fft */
|
||||||
npy_rfftf(nfft,&result_ptr[1],
|
npy_rfftf(nfft,&result_ptr[1],
|
||||||
getvdval(&fft->fft_work,0));
|
getvdval(&fft->fft_work,0));
|
||||||
|
|
||||||
/* Set real part of DC component to first index of the rfft
|
/* Set real part of DC component to first index of the rfft
|
||||||
* routine */
|
* routine */
|
||||||
result_ptr[0] = result_ptr[1];
|
result_ptr[0] = result_ptr[1];
|
||||||
|
|
||||||
result_ptr[1] = 0; /* Set imaginary part of DC component
|
result_ptr[1] = 0; /* Set imaginary part of DC component
|
||||||
* to zero */
|
* to zero */
|
||||||
|
|
||||||
/* For an even fft, the imaginary part of the Nyquist frequency
|
/* For an even fft, the imaginary part of the Nyquist frequency
|
||||||
* bin equals zero.*/
|
* bin equals zero.*/
|
||||||
if(likely(nfft%2 == 0)) {
|
if(likely(nfft%2 == 0)) {
|
||||||
result_ptr[nfft+1] = 0;
|
result_ptr[nfft+1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_overflow_vx(*result);
|
|
||||||
check_overflow_vx(fft->fft_work);
|
check_overflow_vx(fft->fft_work);
|
||||||
|
#elif defined LASP_FFT_BACKEND_FFTW
|
||||||
|
|
||||||
|
d* timedata_ptr = getvdval(timedata,0);
|
||||||
|
c* result_ptr = getvcval(result,0);
|
||||||
|
d_copy(fft->real_storage,timedata_ptr, nfft, 1, 1);
|
||||||
|
|
||||||
|
fftw_execute(fft->forward_plan);
|
||||||
|
|
||||||
|
c_copy(result_ptr, fft->complex_storage, nfft/2+1);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
check_overflow_vx(*result);
|
||||||
feTRACE(15);
|
feTRACE(15);
|
||||||
|
|
||||||
}
|
}
|
||||||
void Fft_fft(const Fft* fft,const dmat* timedata,cmat* result) {
|
void Fft_fft(const Fft* fft,const dmat* timedata,cmat* result) {
|
||||||
fsTRACE(15);
|
fsTRACE(15);
|
||||||
|
|
||||||
dbgassert(fft && timedata && result,NULLPTRDEREF);
|
dbgassert(fft && timedata && result,NULLPTRDEREF);
|
||||||
|
|
||||||
const us nchannels = timedata->n_cols;
|
const us nchannels = timedata->n_cols;
|
||||||
dbgassert(timedata->n_cols == result->n_cols,
|
dbgassert(timedata->n_cols == result->n_cols,
|
||||||
"Number of columns in timedata and result"
|
"Number of columns in timedata and result"
|
||||||
" should be equal.");
|
" should be equal.");
|
||||||
|
|
||||||
for(us col=0;col<nchannels;col++) {
|
for(us col=0;col<nchannels;col++) {
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ typedef struct {
|
|||||||
us stride;
|
us stride;
|
||||||
d* _data;
|
d* _data;
|
||||||
} dmat;
|
} dmat;
|
||||||
|
|
||||||
/// Dense matrix of complex floating point values
|
/// Dense matrix of complex floating point values
|
||||||
typedef struct {
|
typedef struct {
|
||||||
us n_rows;
|
us n_rows;
|
||||||
|
@ -173,6 +173,8 @@ static inline d d_dot(const d a[],const d b[],const us size){
|
|||||||
* @param to : Array to write to
|
* @param to : Array to write to
|
||||||
* @param from : Array to read from
|
* @param from : Array to read from
|
||||||
* @param size : Size of arrays
|
* @param size : Size of arrays
|
||||||
|
* @param to_inc : Mostly equal to 1, the stride of the array to copy to
|
||||||
|
* @param from_inc : Mostly equal to 1, the stride of the array to copy from
|
||||||
*/
|
*/
|
||||||
static inline void d_copy(d to[],
|
static inline void d_copy(d to[],
|
||||||
const d from[],
|
const d from[],
|
||||||
|
@ -20,10 +20,11 @@
|
|||||||
/**
|
/**
|
||||||
* Create a numpy array from an existing dmat.
|
* Create a numpy array from an existing dmat.
|
||||||
*
|
*
|
||||||
* @param mat
|
* @param mat dmat struccture containing array data and metadata.
|
||||||
* @param transfer_ownership
|
* @param transfer_ownership If set to true, Numpy array will be responsible
|
||||||
|
* for freeing the data.
|
||||||
*
|
*
|
||||||
* @return
|
* @return Numpy array
|
||||||
*/
|
*/
|
||||||
static inline PyObject* dmat_to_ndarray(dmat* mat,bool transfer_ownership) {
|
static inline PyObject* dmat_to_ndarray(dmat* mat,bool transfer_ownership) {
|
||||||
fsTRACE(15);
|
fsTRACE(15);
|
||||||
@ -50,7 +51,7 @@ static inline PyObject* dmat_to_ndarray(dmat* mat,bool transfer_ownership) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transpose the array
|
// Transpose the array
|
||||||
PyObject* arr = PyArray_Transpose(arr_t,NULL);
|
PyObject* arr = PyArray_Transpose((PyArrayObject*) arr_t,NULL);
|
||||||
if(!arr) {
|
if(!arr) {
|
||||||
WARN("Array transpose failure");
|
WARN("Array transpose failure");
|
||||||
feTRACE(15);
|
feTRACE(15);
|
||||||
|
@ -6,7 +6,7 @@ Created on Mon Jan 15 19:45:33 2018
|
|||||||
@author: anne
|
@author: anne
|
||||||
"""
|
"""
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from lasp import Fft
|
from lasp.wrappers import Fft
|
||||||
|
|
||||||
nfft=9
|
nfft=9
|
||||||
print('nfft:',nfft)
|
print('nfft:',nfft)
|
||||||
|
Loading…
Reference in New Issue
Block a user