Is there any difference between declaring #param[in] and #param (without [in]) in C libraries? - doxygen

Add info to question:
I'm very new writting this kind of descriptions for my functions.
I can't see any difference between declare function variables description in the library (anylib.h) like
#ifndef MYLIB_H
# define MYLIB_H
/**
* My function description.
*
* #param[in] x Mtrx size x.
* #param[in] y Mtrx size y.
*
* #return Result.
*/
int *my_function(int x, int y);
#endif
(Sorry if image is an url instead image, is because low reputation)
VSCode showing function description in file.c using #param[in]
or declare like
#ifndef MYLIB_H
# define MYLIB_H
/**
* My function description.
*
* #param x Mtrx size x.
* #param y Mtrx size y.
*
* #return Result.
*/
int *my_function(int x, int y);
#endif
VSCode showing function description in file.c using #param
The library is included with -I ( i ) flag
INC = -I include -I ./mylibdir/ -I ./inc/anotherdir/
...
$(OBJDIR)%.o:$(SRCDIR)%.c
#$(CC) $(CFLAGS) $(INC) -o $# -c $<
...
Here I call the function. The path to my lib is no necessary, only the name
#include "mylib.h"
int main(int argc, char *argv[])
{
int a = 3;
int b = 2;
printf("my function result: %i", my_function(a, b));
}
Exist a difference between this?
pd: I dont know the version of Dox. Im in my college mac computer, and i know i have some depracated software versions, idk if its the case

Related

In mex file, I can't overwrite scalar through the pointer in matlab2016a, although I can overwrite the scalar in 2013a and also the array in 2016a

[environment]
OS: OSX10.11 and maxOS Sierra(10.12)
MATLAB: matlab2013a and matlab2016a
Xcode: xcode7 and xcode8
In my work, I must use the following mex file in the old package.
//destructiveMatrixWriteAtIndices.c
//------------------------------------------------------
#include <matrix.h> /* Matlab matrices */
#include <mex.h>
#include <stddef.h> /* NULL */
#define notDblMtx(it) (!mxIsNumeric(it) || !mxIsDouble(it) || mxIsSparse(it) || mxIsComplex(it))
void mexFunction(int nlhs, /* Num return vals on lhs */
mxArray *plhs[], /* Matrices on lhs */
int nrhs, /* Num args on rhs */
const mxArray *prhs[] /* Matrices on rhs */
)
{
double *mtx;
double *newValues;
double *doubleStartIndex;
int i, startIndex, size;
mxArray *arg;
if (nrhs != 3) mexErrMsgTxt("requires 3 arguments.");
/* ARG 1: MATRIX */
arg = prhs[0];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
mtx = mxGetPr(arg);
arg = prhs[1];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
newValues = mxGetPr(arg);
size = (int) mxGetM(arg) * mxGetN(arg);
arg = prhs[2];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
doubleStartIndex = mxGetPr(arg);
startIndex = (int) doubleStartIndex[0];
for (i=0; i<size; i++){
mtx[i+startIndex] = newValues[i];
}
return;
}
//------------------------------------------------------
This mex file is the function to overwrite the scalar and the part of matrix through the pointer.
e.g. in matlab2013a command window (scalar in matlab2013a)
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "3".
e.g. in matlab2013a and matlab2016a command window (matrix in matlab2013a and matlab2016a)
a = [1, 2];
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "[3, 2]".
e.g. in matlab2016a command window (scalar in matlab2016a)
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "1"! Why?
I also used the lldb, and revealed the strange behavior of this code.
In matlab2013a and matlab2016a, when I run the following snippet.
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
The lldb revealed "*mtx = 3" at the end of the mex function in both matlab, but the mex function couldn't pass the result(*mtx = 3, or prhs[0] = 3) through the pointer in the only matlab2016a.
It's very strange behavior!
※I have understood that this mex function is very danger, but this mex function was used at some points in the package that I must use. Therefore, I must fix this mex file and make the package run in matlab2016a.
Please help me.
I'm pretty sure you're not meant to modify the input array in a mex function. More details here Does Matlab ever copy data passed to a mex function?. The "matlab" solution is probably to return the modified array as an output of the mex rather modifying in place.

No Symbols Loaded: libmex.pdb not loaded (throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH : C++ exception)

In order to create a MEX function and use it in my MATLAB code, like this:
[pow,index] = mx_minimum_power(A11,A12,A13,A22,A23,A33);
I've created the file mx_minimum_power.cpp and written the following code in it:
#include <math.h>
#include <complex>
#include "mex.h"
#include "matrix.h"
#include "cvm.h"
#include "blas.h"
#include "cfun.h"
using std::complex;
using namespace cvm;
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
const int arraysize = 62172;
const int matrixDimention = 3;
float *inMatrixA11 = (float *)mxGetPr(prhs[0]);
complex<float> *inMatrixA12 = (complex<float> *)mxGetPr(prhs[1]);
complex<float> *inMatrixA13 = (complex<float> *)mxGetPr(prhs[2]);
float *inMatrixA22 = (float *)mxGetPr(prhs[3]);
complex<float> *inMatrixA23 = (complex<float> *)mxGetPr(prhs[4]);
float *inMatrixA33 = (float *)mxGetPr(prhs[5]);
basic_schmatrix< float, complex<float> > A(matrixDimention);
int i = 0;
for (i = 0; i < arraysize; i++)
{
A.set(1, 1, inMatrixA11[i]);
A.set(1, 2, inMatrixA12[i]);
A.set(1, 3, inMatrixA13[i]);
A.set(2, 2, inMatrixA22[i]);
A.set(2, 3, inMatrixA23[i]);
A.set(3, 3, inMatrixA33[i]);
}
}
And then in order to be able to debug the code, I've created the mx_minimum_power.pdb and mx_minimum_power.mexw64 files, using the following code in the Matlab Command Window:
mex -g mx_minimum_power.cpp cvm_em64t_debug.lib
The files blas.h, cfun.h, cvm.h and cvm_em64t_debug.lib are in the same directory as mx_minimum_power.cpp.
They are the headers and library files of the CVM Class Library.
Then I've attached MATLAB.exe to Visual Studio 2013, using the way explained here.
and have set a breakpoint at line40:
When I run my MATLAB code, there's no error until the specified line.
But if I click on the Step Over button, I'll encounter the following message:
With the following information added to the Output:
First-chance exception at 0x000007FEFCAE9E5D in MATLAB.exe: Microsoft C++ exception: cvm::cvmexception at memory location 0x0000000004022570.
> throw_segv_longjmp_seh_filter()
throw_segv_longjmp_seh_filter(): C++ exception
< throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH
Can you suggest me why libmex.pdb is needed at that line and how should I solve the issue?
If I stop debugging, I'll get the following information in MATLAB Command Window:
Unexpected Standard exception from MEX file.
What() is:First index value 0 is out of [1,4) range
Right before pressing the step over button, we have the following values for A11[0],A12[0],A13[0],A22[0],A23[0],A33[0]:
that are just right as my expectations, according to what MATLAB passes to the MEX function:
Maybe the problem is because of wrong allocation for matrix A, it is as follows just before pressing the step over button.
The problem occurs because we have the following code in lines 48 to 53 of the cvm.h file:
// 5.7 0-based indexing
#if defined (CVM_ZERO_BASED)
# define CVM0 TINT_ZERO //!< Index base, 1 by default or 0 when \c CVM_ZERO_BASED is defined
#else
# define CVM0 TINT_ONE //!< Index base, 1 by default or 0 when \c CVM_ZERO_BASED is defined
#endif
That makes CVM0 = 1 by default. So if we press the Step Into(F11) button at the specified line two times, we will get into line 34883 of the file cvm.h:
basic_schmatrix& set(tint nRow, tint nCol, TC c) throw(cvmexception)
{
this->_set_at(nRow - CVM0, nCol - CVM0, c);
return *this;
}
Press Step Into(F11) at line this->_set_at(nRow - CVM0, nCol - CVM0, c); and you'll go to the definition of the function _set_at:
// sets both elements to keep matrix hermitian, checks ranges
// zero based
void _set_at(tint nRow, tint nCol, TC val) throw(cvmexception)
{
_check_lt_ge(CVM_OUTOFRANGE_LTGE1, nRow, CVM0, this->msize() + CVM0);
_check_lt_ge(CVM_OUTOFRANGE_LTGE2, nCol, CVM0, this->nsize() + CVM0);
if (nRow == nCol && _abs(val.imag()) > basic_cvmMachMin<TR>()) { // only reals on main diagonal
throw cvmexception(CVM_BREAKS_HERMITIANITY, "real number");
}
this->get()[this->ld() * nCol + nRow] = val;
if (nRow != nCol) {
this->get()[this->ld() * nRow + nCol] = _conjugate(val);
}
}
pressing Step Over(F10) button,you'll get the result:
so in order to get nRow=1 and nCol=1 and not nRow=0 and nCol=0, which is out of the range [1,4), you should write that line of code as:
A.set(2, 2, inMatrixA11[i]);

Postgresql c function returning one row with 2 fileds

I'm new in postgresql c function and I start following examples.
I want to write a simple function that has inside an SQL and receiving parameter evaluete and return 2 fields as sum of 2 columns, separately (for now to be simpler).
The function below has problem passing the check
(get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc) != TYPEFUNC_COMPOSITE)
If I remove this line I get 1 integer as result from this query
select * from pdc_imuanno(2012);
and error from
select (a).* from pdc_imuanno(2012) a;
because is not a composite type.
Question is I how I can prepare template for tuple if it's not correct this
resultTupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "abp1", FLOAT4OID, -1, 0);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "abp2", FLOAT4OID, -1, 0);
And more in
get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc)
fcinfo what is and where come from?
source table:
CREATE TABLE imu.calcolo (
codfis character varying(16) NOT NULL,
anno integer NOT NULL,
abp1 numeric,
abp2 numeric,
CONSTRAINT imucalcolo_pkey PRIMARY KEY (codfis, anno)
)
WITH ( OIDS=FALSE );
-------------------------------------------------------
#include "postgres.h"
#include "fmgr.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "executor/spi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include <math.h>
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/numeric.h"
#include "access/htup_details.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(test_query);
Datum test_query(PG_FUNCTION_ARGS);
Datum
test_query(PG_FUNCTION_ARGS)
{
TupleDesc resultTupleDesc, tupledesc;
bool bisnull, cisnull;
Oid resultTypeId;
Datum retvals[2];
bool retnulls[2];
HeapTuple rettuple;
sprintf(query,"SELECT anno, abp1::real, abp2::real "
"FROM imu.calcolo WHERE anno = %d;",PG_GETARG_INT32(0));
int ret;
int proc;
float abp1 = 0;
float abp2 = 0;
SPI_connect();
ret = SPI_exec(query,0);
proc = SPI_processed;
if (ret > 0 && SPI_tuptable != NULL)
{
HeapTuple tuple;
tupledesc = SPI_tuptable->tupdesc;
SPITupleTable *tuptable = SPI_tuptable;
for (j = 0; j < proc; j++)
{
tuple = tuptable->vals[j];
abp1 += DatumGetFloat4(SPI_getbinval(tuple, tupledesc, 2, &bisnull));
abp2 += DatumGetFloat4(SPI_getbinval(tuple, tupledesc, 3, &cisnull));
}
}
resultTupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "abp1", FLOAT4OID, -1, 0);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "abp2", FLOAT4OID, -1, 0);
if (get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc) != TYPEFUNC_COMPOSITE) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context that cannot accept type record")));
}
resultTupleDesc = BlessTupleDesc(resultTupleDesc);
SPI_finish();
retvals[0] = Float4GetDatum(abp1);
retvals[1] = Float4GetDatum(abp2);
retnulls[1] = bisnull;
retnulls[2] = cisnull;
rettuple = heap_form_tuple( resultTupleDesc, retvals, retnulls);
PG_RETURN_DATUM( HeapTupleGetDatum( rettuple ) );
}
creation function:
CREATE FUNCTION pdc_imuanno(integer)
RETURNS float
AS 'pdc','test_query'
LANGUAGE C STABLE STRICT;
ALTER FUNCTION pdc_imuanno(integer) OWNER TO www;
query:
select * from pdc_imuanno(2012);
Ok I find the simple and silly error
I create the function retunrning 1 field by myself and I expeted to see as return 2 fields.
with this creation sql it works
CREATE FUNCTION pdc_imuanno(integer)
RETURNS TABLE(abp1 real, abp2 real)
AS 'pdc','test_query'
LANGUAGE C STABLE STRICT;
Anyway it works with limited number of rows to sum and if I extend the rows number it crash
in this point
rettuple = heap_form_tuple( resultTupleDesc, retvals, retnulls);
I guess there are some error in types for values
so I query on the table fields as numeric::real, I get them as float4 and I output them as datum.
Where is my error?
Thanks a lot for any help.
This in my first post in StackOverflow.
Luca
in:
get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc)
fcinfo - what is and where come from?
fcinfo is part of PG_FUNCTION_ARGS in the v1 calling convention. It's the context of the function call and contains all sorts of details like parameters, etc. Much of this is handled behind the scenes by the GETARG macros, etc, but you need to pass it around to helper functions.
The rest of the question is hard to understand because of the typos etc. I'm guessing that you want to write a function in C to add two values together and return the result? If so, that doesn't make much sense to return as two fields in a composite type. Please show the relevant CREATE TYPE statements, the CREATE OR REPLACE FUNCTION declaration you used to define the function, and explain what you are trying to do and why.
(If you edit your question, post a comment in reply to this answer otherwise or I won't know you edited.)

How to fix number of steps (not time) in Matlab simulink

This may be a simple question.But I couldn't find a way to go around this.I am using an s function block to input a wave signal to my algorithm.wave signal is being read from file of about 2000 points
First i started with simulation time equal to 50.Then it read only 50 points.I checked the 'tout' variable. It was 0,1,2,....50
Then i increased simulation time to 100.still result is same.only 50 points read.But tout is 0,2,4,6..50
I tried up to 10000.Whatever i do it reads 50 values only with wide time step like 0,200,400,600 etc.
Is it a problem with my s-function or simulink settings?
Here is the c s-function file
/* Give S-function a name */
#define S_FUNCTION_NAME Readip
#define S_FUNCTION_LEVEL 2
/* Include SimStruct definition and file I/O functions */
#include "simstruc.h"
#include <stdio.h>
#include <stdlib.h>
static FILE* file2;
/* Called at the beginning of the simulation */
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 0);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
if (!ssSetNumOutputPorts(S, 3)) return;
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
ssSetOutputPortWidth(S, 0, 1);
ssSetOutputPortDataType(S,0,DYNAMICALLY_SIZED);
ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
ssSetOutputPortWidth(S, 1, 1);
ssSetOutputPortDataType(S,1,DYNAMICALLY_SIZED);
ssSetOutputPortOptimOpts(S, 1, SS_REUSABLE_AND_LOCAL);
ssSetOutputPortWidth(S, 2, 1);
ssSetOutputPortDataType(S,2,DYNAMICALLY_SIZED);
ssSetOutputPortOptimOpts(S, 2, SS_REUSABLE_AND_LOCAL);
ssSetNumPWork(S,1);
ssSetNumSampleTimes(S, 1);
}
/* Set sample times for the block */
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
/* Function: mdlStart ========
===============================================
* Abstract:
* This function is called once at start of model execution. If you
* have states that shou
ld be initialized once, this is the place
* to do it.
*/
static void mdlStart(SimStruct *S)
{
/*at start of model execution, open the file and store the pointer
*in the pwork vector */
void** pwork = ssGetPWork(S);
FILE *datafile;
datafile = fopen("table.data","r");
pwork[0] = datafile;
}
#endif /* MDL_START */
/* Function: mdlOutputs =======================================================
* Abstract:
* In this function, you compute the outputs of your S-function
* block. Generally outputs are placed in the output vector, ssGetY(S).
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
//get pointer to the block's output signal
real_T *y1 = ssGetOutputPortSignal(S,0);
real_T *y2 = ssGetOutputPortSignal(S,1);
real_T *y3 = ssGetOutputPortSignal(S,2);
char a[10];
char b[10];
char c[10];
/*get pointer to array of pointers, where the first element is the address
*of the open file */
void** pwork = ssGetPWork(S);
/*read a floating point number and then the comma delimiter
*store the result in y*/
fscanf(pwork[0],"%s %s %s",&a,&b,&c);
*y1=atof(a);
*y2=atof(b);
*y3=atof(c);
}
/* Function: mdlTerminate =====================================================
* Abstract:
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was
* allocated in mdlStart, this is the place to free it.
*/
static void mdlTerminate(SimStruct *S)
{
//close the file
void** pwork = ssGetPWork(S);
FILE *datafile;
datafile = pwork[0];
fclose(datafile);
}
/*=============================*
* Required S-function trailer *
*=============================*/
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
This appears to just be a settings issue. If you do not specify a step-size for your solver and your blocks do not indicate sample time, Simulink will choose a default of Simulation Time / 50. Simply open the Model Configuration Parameters dialog and click on solvers in the left-hand pane. If you are using a fixed-step solver, you can explicitly set the step size. If you are using a variable-step solver, you can specify the max/min step sizes.
Additionally, if you are looking to specify a discrete sample period specifically for your S-function, then you may want to look in to this link to be sure that you are implementing mdlInitializeSampleTimes as desired.
You need to use the fixed step discrete solver.
Set Periodic sample time constraint to 'Unconstrined'
Enter the Fixed-step size and Simulation Stop time so that you get 2000 steps.
For example 1s/step and 2000s stop time, or 0.1s/step and 200s stop time.

FFTW with MEX and MATLAB argument issues

I wrote the following C/MEX code using the FFTW library to control the number of threads used for a FFT computation from MATLAB. The code works great (complex FFT forward and backward) with the FFTW_ESTIMATE argument in the planner although it is slower than MATLAB. But, when I switch to the FFTW_MEASURE argument to tune up the FFTW planner, it turns out that applying one FFT forward and then one FFT backward does not return the initial image. Instead, the image is scaled by a factor. Using FFTW_PATIENT gives me an even worse result with null matrices.
My code is as follows:
Matlab functions:
FFT forward:
function Y = fftNmx(X,NumCPU)
if nargin < 2
NumCPU = maxNumCompThreads;
disp('Warning: Use the max maxNumCompThreads');
end
Y = FFTN_mx(X,NumCPU)./numel(X);
FFT backward:
function Y = ifftNmx(X,NumCPU)
if nargin < 2
NumCPU = maxNumCompThreads;
disp('Warning: Use the max maxNumCompThreads');
end
Y = iFFTN_mx(X,NumCPU);
Mex functions:
FFT forward:
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <mex.h>
# include <matrix.h>
# include <math.h>
# include </home/nicolas/Code/C/lib/include/fftw3.h>
char *Wisfile = NULL;
char *Wistemplate = "%s/.fftwis";
#define WISLEN 8
void set_wisfile(void)
{
char *home;
if (Wisfile) return;
home = getenv("HOME");
Wisfile = (char *)malloc(strlen(home) + WISLEN + 1);
sprintf(Wisfile, Wistemplate, home);
}
fftw_plan CreatePlan(int NumDims, int N[], double *XReal, double *XImag, double *YReal, double *YImag)
{
fftw_plan Plan;
fftw_iodim Dim[NumDims];
int k, NumEl;
FILE *wisdom;
for(k = 0, NumEl = 1; k < NumDims; k++)
{
Dim[NumDims - k - 1].n = N[k];
Dim[NumDims - k - 1].is = Dim[NumDims - k - 1].os = (k == 0) ? 1 : (N[k-1] * Dim[NumDims-k].is);
NumEl *= N[k];
}
/* Import the wisdom. */
set_wisfile();
wisdom = fopen(Wisfile, "r");
if (wisdom) {
fftw_import_wisdom_from_file(wisdom);
fclose(wisdom);
}
if(!(Plan = fftw_plan_guru_split_dft(NumDims, Dim, 0, NULL, XReal, XImag, YReal, YImag, FFTW_MEASURE *(or FFTW_ESTIMATE respectively)* )))
mexErrMsgTxt("FFTW3 failed to create plan.");
/* Save the wisdom. */
wisdom = fopen(Wisfile, "w");
if (wisdom) {
fftw_export_wisdom_to_file(wisdom);
fclose(wisdom);
}
return Plan;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
#define B_OUT plhs[0]
int k, numCPU, NumDims;
const mwSize *N;
double *pr, *pi, *pr2, *pi2;
static long MatLeng = 0;
fftw_iodim Dim[NumDims];
fftw_plan PlanForward;
int NumEl = 1;
int *N2;
if (nrhs != 2) {
mexErrMsgIdAndTxt( "MATLAB:FFT2mx:invalidNumInputs",
"Two input argument required.");
}
if (!mxIsDouble(prhs[0])) {
mexErrMsgIdAndTxt( "MATLAB:FFT2mx:invalidNumInputs",
"Array must be double");
}
numCPU = (int) mxGetScalar(prhs[1]);
if (numCPU > 8) {
mexErrMsgIdAndTxt( "MATLAB:FFT2mx:invalidNumInputs",
"NumOfThreads < 8 requested");
}
if (!mxIsComplex(prhs[0])) {
mexErrMsgIdAndTxt( "MATLAB:FFT2mx:invalidNumInputs",
"Array must be complex");
}
NumDims = mxGetNumberOfDimensions(prhs[0]);
N = mxGetDimensions(prhs[0]);
N2 = (int*) mxMalloc( sizeof(int) * NumDims);
for(k=0;k<NumDims;k++) {
NumEl *= NumEl * N[k];
N2[k] = N[k];
}
pr = (double *) mxGetPr(prhs[0]);
pi = (double *) mxGetPi(prhs[0]);
//B_OUT = mxCreateNumericArray(NumDims, N, mxDOUBLE_CLASS, mxCOMPLEX);
B_OUT = mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxCOMPLEX);
mxSetDimensions(B_OUT , N, NumDims);
mxSetData(B_OUT , (double* ) mxMalloc( sizeof(double) * mxGetNumberOfElements(prhs[0]) ));
mxSetImagData(B_OUT , (double* ) mxMalloc( sizeof(double) * mxGetNumberOfElements(prhs[0]) ));
pr2 = (double* ) mxGetPr(B_OUT);
pi2 = (double* ) mxGetPi(B_OUT);
fftw_init_threads();
fftw_plan_with_nthreads(numCPU);
PlanForward = CreatePlan(NumDims, N2, pr, pi, pr2, pi2);
fftw_execute_split_dft(PlanForward, pr, pi, pr2, pi2);
fftw_destroy_plan(PlanForward);
fftw_cleanup_threads();
}
FFT backward:
This MEX function differs from the above only in switching pointers pr <-> pi, and pr2 <-> pi2 in the CreatePlan function and in the execution of the plan, as suggested in the FFTW documentation.
If I run
A = imread('cameraman.tif');
>> A = double(A) + i*double(A);
>> B = fftNmx(A,8);
>> C = ifftNmx(B,8);
>> figure,imagesc(real(C))
with the FFTW_MEASURE and FFTW_ESTIMATE arguments respectively I get this result.
I wonder if this is due to an error in my code or in the library. I tried different thing around the wisdom, saving not saving. Using the wisdom produce by the FFTW standalone tool to produce wisdom. I haven't seen any improvement. Can anyone suggest why this is happening?
Additional information:
I compile the MEX code using static libraries:
mex FFTN_Meas_mx.cpp /home/nicolas/Code/C/lib/lib/libfftw3.a /home/nicolas/Code/C/lib/lib/libfftw3_threads.a -lm
The FFTW library hasn't been compiled with:
./configure CFLAGS="-fPIC" --prefix=/home/nicolas/Code/C/lib --enable-sse2 --enable-threads --&& make && make install
I tried different flags without success. I am using MATLAB 2011b on a Linux 64-bit station (AMD opteron quad core).
FFTW computes not normalized transform, see here:
http://www.fftw.org/doc/What-FFTW-Really-Computes.html
Roughly speaking, when you perform direct transform followed by inverse one, you get
back the input (plus round-off errors) multiplied by the length of your data.
When you create a plan using flags other than FFTW_ESTIMATE, your input is overwritten:
http://www.fftw.org/doc/Planner-Flags.html