Reputation: 2480
I have a routine that computes the shift-invariant discrete wavelet transform, as specified in the Rice Wavelet Toolbox, in the frequency domain. The code is in MEX (c-syntax) and uses some extra routines to do imaginary polynomials etc. in a separate file.
The source files fsidwt.c, fisidwt.c and the helper routines polyphase.[chm] are zipped together in a file here: http://ubuntuone.com/6zXIIuA3J4OTTlSquycMlz
This code worked without problems in older matlab versions, and other matlab functions depend on it.
Now however, when I compile it now, there is first a warning message
>> mex fisidwt.c polyphase.c % message about different gcc version
>> mex fsidwt.c polyphase.c % message about different gcc version
fsidwt.c: In function ‘multiMRFWD1D’:
fsidwt.c:187: warning: cast to pointer from integer of different size
fsidwt.c:188: warning: cast to pointer from integer of different size
fsidwt.c:189: warning: cast to pointer from integer of different size
fsidwt.c:190: warning: cast to pointer from integer of different size
which is odd because no integers are cast to pointers. But it's only a warning, so let's carry on.
Now the mex files fsidwt and fisidwt compute the forward and inverse frequency-domain shift-ivariant wavelet transform.
My test program is very simple:
>> clear all; len_sig=256; wlevels=3; numsig=1; numtest=1;
% 256 points, 3 wavelet decomposition levels
>> st=4; ts=(1:(len_sig/st))'*(1:st); ts=ts(:); ts=ts*ones(1,numsig); Ts=fft(ts);
% sawtooth with 4 'teeth' of increasing height and its FFT
>> h=[1;1]/sqrt(2); g=qmf(h); h=[h(:) g(:)]; H=fft(h,len_sig);
% Haar wavelet filters and 256-point FFTs
>> [ffs ffd] = fsidwt(Ts, H, wlevels);
% forward wavelet transform
>> ffr=fisidwt(ffs,ffd,cH,levels);
% recontruction
Unfortunately it exits with a segmentation violation whose cause I cannot trace from the core dump output...
The lines in the code [in the zipfile at http://ubuntuone.com/6zXIIuA3J4OTTlSquycMlz], line numbers 187-190 of fsidwt.c, read:
Hfilter2d = (dComplexMat) dComplexMake2D ( hcomp[0], NQ, Q);
Gfilter2d = (dComplexMat) dComplexMake2D ( hcomp[1], NQ, Q);
Detail2d = (dComplexMat) dComplexMake2D ( workspaced, Q, NQ);
Approx2d = (dComplexMat) dComplexMake2D ( workspacec, Q, NQ);
All the LHS are of type
dComplexMat
which is
typedef struct {double r,i;} dComplex;
typedef dComplex *dComplexVec;
typedef dComplexVec *dComplexMat;
All the RHS are of type
(dComplexVec, long, long)
and the code of dComplexMake2D() is:
dComplexMat dComplexMake2D(
dComplexVec array1D,
int width, int height) {
register int i;
dComplexMat theMatrix = (dComplexMat) mxCalloc ( width, sizeof(dComplexVec) );
theMatrix[0]=(dComplexVec)array1D;
for(i=1;i<width;i++)
theMatrix[i] = theMatrix[i-1] + height;
return theMatrix;
}
How would I start finding the cause of this segmentation violation? Does it have to do with the warning? Is it the new Matlab version? Or the 64-bit architecture?
Upvotes: 3
Views: 458
Reputation: 2480
Oh dear. The MathWorks helpdesk found, as they were investigating this, that the function header for dComplexMake2D
had an extra d
that I must have overlooked at least 42 times.
So embarrassing. But anyway, the code works like a dream (will put it online soon) and a lesson learned:
MEX warned about the return type of dComplexMake2D
as it could not find a matching header, carried on (as it appears to do) but assumed return type int
, linked to the compiled file where dComplexMake2D
returns a pointer (a long int
sized type) and that's where things went wrong...
Thanks to the tech support at MathWorks. They did point out that debugging MEX files is not in any way their business.
Upvotes: 1