I am new to Fourier transform so I hope someone could help!
I want to calculate the wave vector of the Fourier transform, which is why I am doing this test programme.
Basically I have vector u. I apply a Fourier transform to make a vector uf. Then I apply a convolution with a Gaussian function. The code in Scilab looks like this
u = [0.1 -0.1 -0.1 -0.1 0.1 0.1 -0.1 0.1 0.1 -0.1];
sizeu = size(u,'*');
// wave vector
for i=1:sizeu
q(i) = (i-1) * 2 * %pi / sizeu;
end
// forward transform
uf = fft(u);
// convolution with a Gaussian function
for i=2:sizeu
vf(i) = uf(i)*exp(-q(i)*q(i));
end
// backward transform
v = ifft(vf);
So I believe the result, i.e. the vector v should be a real vector. But it is actually a complex vector. I think the error is in the wave vector q but I don't know the correct answer.
Ok, I found it:
When scilab performs fft, the data in freq-space are swapped. Sometimes, there's no problem, because if you use ifft after fft, the ifft function will undo the swap. But, if isn't your objective to use ifft after the fft, or you have to make the product of an fft-transformed function with some non-swapped vector, you'll have troubles, because the frequency components of the functions aren't matched. The solution is to swap the gaussian function to match its values to the test function, using fftshift. Do not undo the swap of the test function to match to gaussian, because when you perform ifft, this function will undo the swap. So, here's the correct code:
u = [0.1 -0.1 -0.1 -0.1 0.1 0.1 -0.1 0.1 0.1 -0.1];
sizeu = size(u,'*');
// wave vector
q = (0:sizeu-1) * 2 * %pi / sizeu;
// forward transform
uf = fft(u);
// convolution with a Gaussian function
vf(2:$) = uf(2:$).*fftshift(exp(-q(2:$).*q(2:$)));
// backward transform
v = ifft(vf);
I cleaned some unnecessary fors, and didn't understand why you do the convolution from i=2 up to $ (last number of vector), and not from i=1. If going from i=1 up to $, remove (2:$) terms.
Related
I am trying to plot a simple equation in MATLAB.
The equation is
z = x^2 - y^2, for -3 <= x <= 3, -3 <= y <= 3.
The current code that I have is
x = -3:3;
y = -3:3;
z = (x.^2) - (y.^2);
plot(z)
The result is
Please help me in this case because I am not sure if the code and graph is correct. Thank you very much.
This is not a piecewise function. A Piecewise Function is a function defined by multiple sub-functions, where each sub-function applies to a different interval in the domain. There is only one function here that takes two arrays of the same length. The calculations yield a vector of zeros, due to the input arrays. If you change either one of the vectors, that is "x" or "y", you will see a nonzero plot. Your code works as expected.
There is a lot going wrong here: Let's start at the beginning:
x = -3:3;
y = -3:3;
If we evaluate these they both will return an vector of integers:
x =
-3 -2 -1 0 1 2 3
This means that the grid on which the function is evaluated is going to be very coarse. To alleviate this you can define a step size, e.g. x = 3:0.1:3 or use linspace, in which case you set the number of samples, so e.g. x = linspace(-3, 3, 500). Now consider the next line:
z = (x.^2) - (y.^2);
If we evaluate this we get
z =
0 0 0 0 0 0 0
and you plot this vector with the 2d-plotting function
plot(z)
which perfectly explains why you get a straight line. This is because the automatic broadcasting of the arithmetic operators like minuse (-) just subtracts values entry-wise. You however want to evaluate z for each possible pair of values of x and y. To do this and to get a nice plot later you should use meshgrid, and use a plotting function like mesh to plot it. So I'd recommend using
[X,Y] = meshgrid(x,y);
to create the grid and then evaluate the function on the grid as follows
Z = X.^2 - Y.^2;
and finally plot your function with
mesh(X,Y,Z);
I have been trying to get the numerical solution to the following system of ordinary differential equations:
Equations for the movement of a body through air in a inclined lunch:
(apparently LaTeX doesn't work on stack overflow)
u'= -F(u, theta, t)*cos(theta)
v'= -F(v, theta, t)*sin(theta)-mg
by the Runge-Kutta-Fehlberg Algorithm, but in the middle of the computation i have to calculate theta, that is calculated by
arccos(u/sqrt(u^2+v^2)) or arcsin(v/sqrt(u^2+v^2)),
but eventually theta gets too small and I need it to solve the function F( v, theta, t) and to find the value V = sqrt(v^2 + u^2) I use V = (v/sin(theta)), but as theta gets small so does sin(theta) and I get a numerical error from a given iteration forward -1.IND00, It is problably because theta is too small, i tried to make theta go from a small positive angle like 0.00001 to a small negative angle like -0.00001 (if(fabs(theta)<0.00001) theta = -0.00001) but it seems that theta gets trapped into this negative value, does anyone have an indication on what to do to resolve this numerical instability ?
It is a bad idea to use the inverse cosine or sine functions to determine the angle of a point. To get
theta = arg ( u + i*v)
use
theta = atan2(v,u).
This still has the problem that it jumps on the negative half axis, that is for v=0, u<0. That can be solved by making theta a third dynamical variable, so that
theta' = Im( (u'+i*v')/(u+i*v) ) = (u*v' - u'*v) / (u^2+v^2)
But really, the equation for the free fall with air friction is easiest implemented as
def friction(vx, vy):
v = hypot(vx, vy)
return k*v
def freefall_ode(t, u):
rx, ry, vx, vy = u
f=friction(vx, vy)
ax = -f*vx
ay = -f*vy - g
return array([ vx, vy, ax, ay ])
so that you do not need any angle or to try to weaken the coupling of the velocity components by reducing it to the angle of the velocity vector. This you can now plug into the integration method of your choice, applied as a method for vector-valued systems.
How do you approximate a function for interpolated points? I use the natural cubic spline to interpolate points as follows for n = 500 points:
t=[0; 3; 6; 9]
z=[0; 6; 6; 0]
plot(t,z,'ro')
ti=linspace(0,9,500)
zn = natcubicspline(t,z,ti)
yn = line(ti,zn)
Is there any way approximate a function for these n-many points (for large n)? Or are there ways to treat interpolated points as if they are a function, i.e. find the gradient of the zn vector? Because zn is a vector of constants, this wouldn't necessarily be helpful.
Update: In particular, my data appears to form a 2nd degree polynomial, so I went ahead and used the following Matlab function to fit my data:
p = polyfit(transpose(ti),zn,2)
Which yields coefficient estimates for a 2nd degree polynomial. It does fit the data, but with high error values, and I have to multiply this coefficient vector by a vector [1 z z^2] to get the correct polynomial. Is there any way to streamline this?
according to the CUDA programming guide, the value returned by the texture fetch is
tex(x) = (1-a)T[i] + aT[i+1] for a one-dimensional texture
where i = floor(Xb), a = frac(Xb), Xb=x-0.5
Suppose we have a one dimensional texture that only has two texals. For example:
T[0] = 0.2, T[1] = 1.5
Say we want to fetch the texal at 1, which I think should return T[1] which is 1.5.
However, if you follow the rule given in the programming guide, the return value will be:
Xb = 1 - 0.5 = 0.5
a = 0.5
i = 0
return value = 0.5*T[0] + 0.5*T[1] = 0.85
which does not make any sense to me. Can someone explain why the linear filtering is done in such way by CUDA? Thanks
The linear filtering algorithm in CUDA assumes texel values are located at the centroid of the interpolation volume (so voxel centered, if you like). In your 1D filtering example, the input data is implicitly taken as
T[0]=(0.5, 0.2) T[1]=(1.5, 1.5)
So your example is asking for Tex(1), which is the midpoint between the two texel values, ie.
0.5*0.2 + 0.5*1.5 = 0.85
To get T[1] returned you would require Tex(1.5) and that is the general rule - add 0.5 to coordinates if you want to treat the texture data as being at the voxel vertices, rather than the voxel center.
I'm playing with octave's fft functions, and I can't really figure out how to scale their output: I use the following (very short) code to approximate a function:
function y = f(x)
y = x .^ 2;
endfunction;
X=[-4096:4095]/64;
Y = f(X);
# plot(X, Y);
F = fft(Y);
S = [0:2047]/2048;
function points = approximate(input, count)
size = size(input)(2);
fourier = [fft(input)(1:count) zeros(1, size-count)];
points = ifft(fourier);
endfunction;
Y = f(X); plot(X, Y, X, approximate(Y, 10));
Basically, what it does is take a function, compute the image of an interval, fft-it, then keep a few harmonics, and ifft the result. Yet I get a plot that is vertically compressed (the vertical scale of the output is wrong). Any ideas?
You are throwing out the second half of the transform. The transform is Hermitian symmetric for real-valued inputs and you have to keep those lines. Try this:
function points = approximate(inp, count)
fourier = fft(inp);
fourier((count+1):(length(fourier)-count+1)) = 0;
points = real(ifft(fourier)); %# max(imag(ifft(fourier))) should be around eps(real(...))
endfunction;
The inverse transform will invariably have some tiny imaginary part due to numerical computation error, hence the real extraction.
Note that input and size are keywords in Octave; clobbering them with your own variables is a good way to get really weird bugs down the road!
You are probably doing it wrong. You remove all the "negative" frequencies in your code. You should keep both positive and negative low frequencies. Here is a code in python and the result. The plot has the right scale.
alt text http://files.droplr.com/files/35740123/XUl90.fft.png
The code:
from __future__ import division
from scipy.signal import fft, ifft
import numpy as np
def approximate(signal, cutoff):
fourier = fft(signal)
size = len(signal)
# remove all frequencies except ground + offset positive, and offset negative:
fourier[1+cutoff:-cutoff] = 0
return ifft(fourier)
def quad(x):
return x**2
from pylab import plot
X = np.arange(-4096,4096)/64
Y = quad(X)
plot(X,Y)
plot(X,approximate(Y,3))