How to implement ifft in matlab? - matlab

I have been having a big problem understanding the concept of numerical ifft.
Consider a function in spatial domain like f(x)=-2/pi*Ln(abs(x)) in which x is between -Lx and Lx. The fourier transform of this function is F(w)=2/abs(w).
I want to figure out whether these two are numerically the same using ifft command in Matlab. If you run the simple code below, you will see the difference that bothers me:
clc
clear all
Lx=0.0005;
N=pow2(10);
dx=2*Lx/(N-1);
w=pi/(N*dx)*linspace(-N/2,N/2,N);
Hw=2./abs(w);
hx=1/dx*abs(fftshift(ifft(Hw)));
x=linspace(-Lx,Lx,N);
hxexact=-2/pi.*log(abs(x));
plot(x,hx,x,hxexact,'r')
legend('ifft','exact')
here is the output:
I would appreciate that if anyone could help me with this.

You seem to have some confusion about the FFT for your function, the result you might have been looking for is:
sqrt(2./pi) / w
This is the fft of your function IFF w is positive!
This is the FFT in the general case:
If you use MATLAB's fft function instead of using your own 2./abs(w) you will see that the ifft and the original function align.

Related

Why i am getting blank graph?How can i solve this issue?

I am trying to plot symbolic variable in MATLAB, for which I have used the same strategy that is available in an answer to a similar question.
This is my code, which outputs a blank graph:
syms t w
x=exp(-t^2)
h=exp(-t)*heaviside(t)+exp(t)*heaviside(-t)
X=fourier(x,w);
H=fourier(h,w);
right=ifourier( rewrite(X*H, 'exp'),t)
fplot(right,[0 8])
How can I make the graph appear?
The problem is that MATLAB ifourier function cannot compute the inverse Fourier transform of the product X*H.
Check that X*H returns:
X*H
Rewriting the expression does not change it at all:
rewrite(X*H, 'exp')
Either way, when computing the inverse Fourier transform:
right=ifourier( X*H,t)
Documentation on the ifourier function states that:
If ifourier cannot transform the input, then it returns an unevaluated
call to fourier.
Since it cannot evaluate explicitly the function, it cannot plot it.

Radon Transform derivation Matlab, finding reasonable F(x,y)

For a project in the University I am working with several "Quality Assessement" metrics on Finger-Vein images.
Now I try to implement a metric that uses the Radon Transform and I got stuck at some point doing this in Matlab.
My problem is as follows:
I got the following formula for the Radon Transform. In the first steps I used the built in one in Matlab, but for further implementing the metric I need the derivation of the thing for the Curvature of the curve.
the delta is the dirac-delta function.
Derivation:
So my intention is to calculate the Radon Transform on my own with the formula but my problem is that F(x,y) is the gray value of the pixel located at (x,y). And so I need a Function F(x,y) that gives me the gray value of the pixel that I can put in to calculate the derivates and the double integral.
How can I get such a function? Or got I do some kind of "Curve Fitting" with my values of the pixels that I get a function?
Thanks in advance.
As I understand your question, there are two things that you could do:
Compute the derivatives of the Radon transform numerically (as suggested by Ander Biguri in a comment above). If you compute the Radon transform carefully, it will be a band-limited function, making the computation of derivatives possible. See this paper for some ideas on how to enforce a band-limited transform:
"The generalized Radon transform: sampling, accuracy and memory considerations" (PDF).
Compute the derivatives of the image numerically, then sample those derivatives to compute your C function. That is, you compute dF/dx, dF/dy, d^2F/dx^2, and whichever derivatives you need as images. You can interpolate into these derivatives if you need more precision.
IMO the best way to compute derivatives of a discrete image is through Gaussian derivatives. Note that this applies to both solutions above. For example dF/dx (Fx) can be computed by (see here for more details):
h = fspecial('gaussian',[1,2*cutoff+1],sigma);
dh = h .* (-cutoff:cutoff) / (-sigma^2);
Fx = conv2(dh,h,F,'same');
PS: sorry for all the self-references, but I have worked on these topics quite a bit in the past. :)

symmetric FFT in matlab

I'm going to implement OFDM system in matlab. I need to take IFFT symmetric from data and then again FFT from results. the IFFT goes right, but the FFT doesn't, fisrt half of result numbers are like data bef0r IFFT, but second half is wrong. I just don't know should I use FFT function when I know the IFFT took 'symmetric'.
here is the functions I used:
x_ifft=ifft(x1, 'symmetric')
x_fft=fft(x_ifft);
Thank you
You should not use "symmetric", but should use fftshift either after ifft or after fft.

Plotting and finding roots of bessel functions

I am trying to plot roots of a function that is composed of multiple bessel functions being added and multiplied in Matlab. The equation is Jm(omega)*Ik(omega)+Im(omega)*Jk(omega) where Jm is the bessel function of the first kind of order m (besselj). Im is the modified bessel function of the first kind of order m (besseli). For each mode m=o,1,2,...and n=1,2,3... The frequency omega(mn) is the corresponding root of the listed equation. m=0,1,2 n-1,2,3,4. I need to solve the equation for the 12 roots. I am new to Matlab and this is a little out of my league. So far I have this code but I wasn't sure if I needed the variable omega in the script or not. I have also looked at other people's questions on the suject but didn't see any quite like this. The plots I have seen look nothing like mine which tells me I am probably wrong. Thanks for any help.
m=(0:2); k=(1:3); n=(1:4);
Jm=besselj(m,n');
Ik=besseli(k,n');
Jk=besselj(k,n');
Im=besseli(m,n');
g=Jm.*Ik+Im.*Jk
plot(g)
Plotting
besselj and besseli take what you call omega as their second parameter, so to plot your function you should try something like
m=0; k=1; omega=0:0.02:10;
Jm=besselj(m,omega);
Ik=besseli(k,omega);
Jk=besselj(k,omega);
Im=besseli(m,omega);
g=Jm.*Ik+Im.*Jk;
plot(omega,g);
hold all;
plot(omega,0,'k');
axis([min(omega) max(omega) -100 100]);
This shows you that for m=1, k=1 the first zeros are around 3.2, 6.3 and 9.4:
Finding the roots numerically
You could implement Halley's method for your function g, similar to how the roots of besselj are determined in the MatlabCentral file linked by Cheery.

Cross-correlation in matlab without using the inbuilt function?

can someone tell how to do the cross-correlation of two speech signals (each of 40,000 samples) in MATLAB without using the built-in function xcorr and the correlation coefficient?
Thanks in advance.
You can do cross-correlations using fft. The cross-correlation of two vectors is simply the product of their respective Fourier transforms, with one of the transforms conjugated.
Example:
a=rand(5,1);
b=rand(5,1);
corrLength=length(a)+length(b)-1;
c=fftshift(ifft(fft(a,corrLength).*conj(fft(b,corrLength))));
Compare results:
c =
0.3311
0.5992
1.1320
1.5853
1.5848
1.1745
0.8500
0.4727
0.0915
>> xcorr(a,b)
ans =
0.3311
0.5992
1.1320
1.5853
1.5848
1.1745
0.8500
0.4727
0.0915
If there some good reason why you can't use the inbuilt, you can use a convolution instead. Cross-correlation is simply a convolution without the reversing, so to 'undo' the reversing of the correlation integral you can first apply an additional reverse to one of your signals (which will cancel out in the convolution).
Well yoda gave a good answer but I thought I mention this anyway just in case. Coming back to the definition of the discrete cross correlation you can compute it without using (too much) builtin Matlab functions (which should be what Matlab do with xcorr). Of course there is still room for improvment as I did not try to vectorize this:
n=1000;
x1=rand(n,1);
x2=rand(n,1);
xc=zeros(2*n-1,1);
for i=1:2*n-1
if(i>n)
j1=1;
k1=2*n-i;
j2=i-n+1;
k2=n;
else
j1=n-i+1;
k1=n;
j2=1;
k2=i;
end
xc(i)=sum(conj(x1(j1:k1)).*x2(j2:k2));
end
xc=flipud(xc);
Which match the result of the xcorr function.
UPDATE: forgot to mention that in my opinion Matlab is not the appropriate tool for doing real time cross correlation of large data sets, I would rather try it in C or other compiled languages.