I am doing fixed point FFT on 8bit pic microcontrller using C language, i am able to get the FFT result from the sample i have taken but i am getting wrong output when i do the IFFT for the FFT result.
The flow of program i am doing is as follows
Doing FFT for 8 samples say example: Real value are (1,0,0,0,0,0,0,0) and Imaginary values are (0,0,0,0,0,0,0,0)
The output of the FFT is (1,1,1,1,1,1,1,1) and imaginary values are (0,0,0,0,0,0,0,0)
Then taking the conjugate of FFT output
Doing FFT for the conjugated result
Again taking the conjugate of the second time FFT result
Finally dividing by 8 to get the original samples in time domain
The output is Real value are (1,0,0,0,0,0,0,0) and Imaginary values are (0,-0,-0,-0,-0,-0,-0,-0);
But if i apply the same for Real values (1,2,3,4,5,6,7,8) and imaginary values (0,0,0,0,0,0,0,0) i am getting wrong result such as real value after IFFT are (1,2,4,7,4,5,4,5) and Imaginary values are(-0,-3,-1,-0,1,0,0,2)
please help me what i am doing wrong...
The FFT solves an interpolation problem, the IFFT the corresponding multi-point evaluation problem
The result of the FFT are coefficients of a polynomial p(z) where p(wk)=xk, w is the unit root associated with the dimension D of the FFT.
Denote with ps,k(z) the polynomial formed from the subsequence of coefficients of p(z) starting in k and spaced with index distance s.
If D=2N is even, the general idea to get from the values to the coefficients is to use wN=-1 and the decomposition
p(z) = p2,0(z²) + z * p2,1(z²)
in the relations
xk = p(wk)=p2,0(w2k) + wk * p2,1(wk)
xN+k = p(wN+k) = p(-wk)
= p2,0(w2k) - wk * p2,1(w2k)
to reduce the big interpolation problem into two subproblems of half the size,
2*p2,0(w2k) = xk + xN+k
2*p2,1(w2k) = w-k * (xk - xN+k)
In the next step,
p2,0 is reduced to p4,0 and p4,2, and
p2,1 is reduced to p4,1 and p4,3
etc.
For the sequence of 8 inputs, one gets in the first step w=(1+i)/sqrt(2) and w2=i
x1,0 = 2*p2,0( 1) = x0 + x4
x1,2 = 2*p2,0( i) = x1 + x5
x1,4 = 2*p2,0(-1) = x2 + x6
x1,6 = 2*p2,0(-i) = x3 + x7
..
x1,1 = 2*p2,1( 1) = (x0 - x4)*1
x1,3 = 2*p2,1( i) = (x1 - x5)*(1-i)/sqrt(2)
x1,5 = 2*p2,1(-1) = (x2 - x6)*(-i)
x1,7 = 2*p2,1(-i) = (x3 - x7)*(-1-i)/sqrt(2)
In the next step, one gets w=i and w2=-1
x2,0 = 4*p4,0( 1) = x1,0 + x1,4
x2,4 = 4*p4,0(-1) = x1,2 + x1,6
..
x2,2 = 4*p4,2( 1)= (x1,0 - x1,4)*1
x2,6 = 4*p4,2(-1)= (x1,2 - x1,6) * (-i)
--
x2,1 = 4*p4,1( 1) = x1,1 + x1,5
x2,5 = 4*p4,1(-1) = x1,3 + x1,7
..
x2,3 = 4*p4,3( 1)= (x1,1 - x1,5)*1
x2,7 = 4*p4,3(-1)= (x1,3 - x1,7) * (-i)
and finally the FFT coefficients Xk=x3,k using w=-1 and w²=1
X0 = 8*p8,0( 1) = x2,0 + x2,4
X4 = 8*p8,4( 1) = (x2,0 - x2,4)*(-1)
--
X2 = 8*p8,2( 1) = x2,2 + x2,6
X6 = 8*p8,6( 1) = (x2,2 - x2,6)*(-1)
--
X1 = 8*p8,1( 1) = x2,1 + x2,5
X5 = 8*p8,5( 1) = (x2,1 - x2,5)*(-1)
--
X3 = 8*p8,3( 1) = x2,3 + x2,7
X7 = 8*p8,7( 1) = (x2,3 - x2,7)*(-1)
Please check that these steps are reflected in your code, especially, that the square root of 2 occurs at the necessary places. It is highly unlikely that the output of random integer inputs is again strictly integer.
In your description there, at no point do you take an inverse DFT.
Think about what is going on, lets say you have the the DFT result as X, taking X*X is going to give you the power spectrum, not an inverse DFT. Then preforming an DFT on this will not give you a time domain, it will give you nonsense.
you need to find the inverse DFT function in the library you are using.
Related
I have a system of nonlinear differential equations for a 3 degree of freedom vibratory system.
system of differential equations
First I want to plot y, y_L and y_R against time (for a given value for Omega) and then I want to plot the domains (max values of y, y_L and y_R) against various amounts of Omega.
Unfortunately, I am not good at Octave. I have written the following code in Octave (based on a sample given by one of the users), but it ends with this error: "anonymous function bodies must be single expressions".
I would be grateful if anyone can help me.
Here is the code:
Me = 4000;
me = 20;
c = 2000;
c1 = 700;
c2 = 700;
k = 20000;
k1 = 250000;
k2 = 20000;
a0 = 0.01;
om = 25;
mu1 = (c+2*c2)/(Me);
mu2 = (c2)/(Me);
mu3 = (c1+c2)/(me);
mu4 = (c2)/(me);
w12 = (2*k2)/(Me);
w22 = (k1+k2)/(me);
a1 = (k2)/(me);
a2 = (k)/(Me);
F0 = (k1*a0)/(Me);
couplode = #(t,y) [y(2); mu4*y(4) - mu3*y(2) - w22*y(1) + a1*y(3) + F0*cos(om*t); y(4); mu2*(y(2)+y(6)) - mu1*y(4) - w12*y(3) + 0.5*w12*(y(1)+y(5)) + a2((y(3)).^3; y(6); mu4*y(4) - mu3*y(6) - w22*y(5) + a1*y(3) + F0*cos(om*t)];
[t,y] = ode45(couplode, [0 0.49*pi], [1;1;1;1;1;1]*1E-8);
figure(1)
plot(t, y)
grid
str = {'$$ \dot{y_L} $$', '$$ y_L $$', '$$ \dot{y} $$', '$$ y $$', '$$ \dot{y_R} $$', '$$ y_R $$'};
legend(str, 'Interpreter','latex', 'Location','NW')
You have a strange term rather at the end of the vector definition
... + a2((y(3)).^3
You certainly meant
... + a2*y(3).^3
You get better visibility and easier debugging by breaking that into separate lines
couplode = #(t,y) [ y(2);
mu4*y(4)-mu3*y(2)-w22*y(1)+a1*y(3)+F0*cos(om*t);
y(4);
mu2*(y(2)+y(6)) - mu1*y(4) - w12*y(3) + 0.5*w12*(y(1)+y(5)) + a2*y(3).^3;
y(6);
mu4*y(4)-mu3*y(6)-w22*y(5)+a1*y(3)+F0*cos(om*t)];
At least in this form, spaces or no spaces makes no difference. In general in matlab/octave [a +b -c] is the same as [a, +b, -c], so one has to be careful that the expression is not interpreted as matrix row. Spaces on both sites of the operation sign switches back to the single-expression interpretation.
I have two data files, each of them contain a big number of 3-dimensional points (file A stores approximately 50,000 points, file B stores approximately 500,000 points). My goal is to find for every point (a) in file A the point (b) in file B which has the smallest distance to (a). I store the points in two lists like this:
List A nodes:
(ID X Y Z)
[ ['478277', -107.0, 190.5674, 128.1634],
['478279', -107.0, 190.5674, 134.0172],
['478282', -107.0, 190.5674, 131.0903],
['478283', -107.0, 191.9798, 124.6807],
... ]
List B data:
(X Y Z Data)
[ [-28.102, 173.657, 229.744, 14.318],
[-28.265, 175.549, 227.824, 13.648],
[-27.695, 175.925, 227.133, 13.142],
...]
My first approach was to simply iterate through the first and second list with a nested loop and compute the distance between every points like this:
outfile = open(job[0] + '/' + output, 'wb');
dist_min = float(job[5]);
dist_max = float(job[6]);
dists = [];
for node in nodes:
shortest_distance = 1000.0;
shortest_data = 0.0;
for entry in data:
dist = math.sqrt((node[1] - entry[0])**2 + (node[2] - entry[1])**2 + (node[3] - entry[2])**2);
if (dist_min <= dist <= dist_max) and (dist < shortest_distance):
shortest_distance = dist;
shortest_data = entry[3];
outfile.write(node[0] + ', ' + str('%10.5f' % shortest_data + '\n'));
outfile.close();
I recognized that the amount of loops Python has to run is way too big (~25,000,000,000), so I had to fasten my code. I tried to first calculate all distances with list comprehensions but the code still is too slow:
p_x = [row[1] for row in nodes];
p_y = [row[2] for row in nodes];
p_z = [row[3] for row in nodes];
q_x = [row[0] for row in data];
q_y = [row[1] for row in data];
q_z = [row[2] for row in data];
dx = [[(px - qx) for px in p_x] for qx in q_x];
dy = [[(py - qy) for py in p_y] for qy in q_y];
dz = [[(pz - qz) for pz in p_z] for qz in q_z];
dx = [[dxxx * dxxx for dxxx in dxx] for dxx in dx];
dy = [[dyyy * dyyy for dyyy in dyy] for dyy in dy];
dz = [[dzzz * dzzz for dzzz in dzz] for dzz in dz];
D = [[(dx[i][j] + dy[i][j] + dz[i][j]) for j in range(len(dx[0]))] for i in range(len(dx))];
D = [[(DDD**(0.5)) for DDD in DD] for DD in D];
To be honest, at this point, I do not know which of the two approaches is better, anyway, none of the two possibilities seem feasible. I'm not even sure if it is possible to write a code which calculates all distances in an acceptable time. Is there even another way to solve my problem without calculating all distances?
Edit: I forgot to mention that I am running on Python 2.5.1 and am not allowed to install or add any new libraries...
Just in case someone is interrested in the solution:
I found a way to speed up the whole process by not calculating all distances:
I created a 3D-list, representing a grid in the given 3D space, divided in X, Y and Z in a given step size (e.g. (Max. - Min.) / 1,000). Then I iterated over every 3D point to put it into my grid. After that I iterated over the points of set A again, looking if there are points from B in the same cube, if not I would increase the search radius, so the process is looking in the adjacent 26 cubes for points. The radius is increasing until there is at least one point found. The resulting list is comparatively small and can be ordered in short time and the nearest point is found.
The processing time went down to a couple minutes and it is working fine.
p_x = [row[1] for row in nodes];
p_y = [row[2] for row in nodes];
p_z = [row[3] for row in nodes];
q_x = [row[0] for row in data];
q_y = [row[1] for row in data];
q_z = [row[2] for row in data];
min_x = min(p_x + q_x);
min_y = min(p_y + q_y);
min_z = min(p_z + q_z);
max_x = max(p_x + q_x);
max_y = max(p_y + q_y);
max_z = max(p_z + q_z);
max_n = max(max_x, max_y, max_z);
min_n = min(min_x, min_y, max_z);
gridcount = 1000;
step = (max_n - min_n) / gridcount;
ruler_x = [min_x + (i * step) for i in range(gridcount + 1)];
ruler_y = [min_y + (i * step) for i in range(gridcount + 1)];
ruler_z = [min_z + (i * step) for i in range(gridcount + 1)];
grid = [[[0 for i in range(gridcount)] for j in range(gridcount)] for k in range(gridcount)];
for node in nodes:
loc_x = self.abatemp_get_cell(node[1], ruler_x);
loc_y = self.abatemp_get_cell(node[2], ruler_y);
loc_z = self.abatemp_get_cell(node[3], ruler_z);
if grid[loc_x][loc_y][loc_z] is 0:
grid[loc_x][loc_y][loc_z] = [[node[1], node[2], node[3], node[0]]];
else:
grid[loc_x][loc_y][loc_z].append([node[1], node[2], node[3], node[0]]);
for entry in data:
loc_x = self.abatemp_get_cell(entry[0], ruler_x);
loc_y = self.abatemp_get_cell(entry[1], ruler_y);
loc_z = self.abatemp_get_cell(entry[2], ruler_z);
if grid[loc_x][loc_y][loc_z] is 0:
grid[loc_x][loc_y][loc_z] = [[entry[0], entry[1], entry[2], entry[3]]];
else:
grid[loc_x][loc_y][loc_z].append([entry[0], entry[1], entry[2], entry[3]]);
out = [];
outfile = open(job[0] + '/' + output, 'wb');
for node in nodes:
neighbours = [];
radius = -1;
loc_nx = self.abatemp_get_cell(node[1], ruler_x);
loc_ny = self.abatemp_get_cell(node[2], ruler_y);
loc_nz = self.abatemp_get_cell(node[3], ruler_z);
reloop = True;
while reloop:
if neighbours:
reloop = False;
radius += 1;
start_x = 0 if ((loc_nx - radius) < 0) else (loc_nx - radius);
start_y = 0 if ((loc_ny - radius) < 0) else (loc_ny - radius);
start_z = 0 if ((loc_nz - radius) < 0) else (loc_nz - radius);
end_x = (len(ruler_x) - 1) if ((loc_nx + radius + 1) > (len(ruler_x) - 1)) else (loc_nx + radius + 1);
end_y = (len(ruler_y) - 1) if ((loc_ny + radius + 1) > (len(ruler_y) - 1)) else (loc_ny + radius + 1);
end_z = (len(ruler_z) - 1) if ((loc_nz + radius + 1) > (len(ruler_z) - 1)) else (loc_nz + radius + 1);
for i in range(start_x, end_x):
for j in range(start_y, end_y):
for k in range(start_z, end_z):
if not grid[i][j][k] is 0:
for grid_entry in grid[i][j][k]:
if not isinstance(grid_entry[3], basestring):
neighbours.append(grid_entry);
dists = [];
for n in neighbours:
d = math.sqrt((node[1] - n[0])**2 + (node[2] - n[1])**2 + (node[3] - n[2])**2);
dists.append([d, n[3]]);
dists = sorted(dists);
outfile.write(node[0] + ', ' + str(dists[0][-1]) + '\n');
outfile.close();
Function to get the position of a point:
def abatemp_get_cell(self, n, ruler):
for i in range(len(ruler)):
if i >= len(ruler):
return False;
if ruler[i] <= n <= ruler[i + 1]:
return i;
The gridcount variable gives one the chance to fasten the process, with a small gridcount the process of sorting the points into the grid is very fast, but the lists of neighbours in the search loop gets bigger and more time is needed for this part of the process. With a big gridcount more time is needed at the beginning, however the loop runs faster.
The only issue I have now is the fact, that there are cases when the process found neighbours but there are other points, which are not yet found, but are closer to the point (see picture). So far I solved this issue by incrementing the search radius another time when there are already neigbours. And still then I have points which are closer but not in the neighbours list, although it's a very small amount (92 out of ~100,000). I could solve this problem by increment the radius two times after finding neighbours, but this solution seems not very smart. Maybe you guys have an idea...
This is the first working draft of the process, I think it will be possible to improve it even more, just to give you an idea of how it is working...
It took me a bit of thought but at the end I think I found a solution for you.
Your problem is not in the code you wrote but in the algorithm it implements.
There is an algorithm called Dijkstra's algorithm and here is the gist of it: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm .
Now what you need to do is to use this algorithm in a clever way:
create a node S (stand for source).
Now link edges from S to all the nodes in B group.
After you done that you should link edges from each point b in B to each point a in A.
You should set the cost of the links from the source to 0 and the other to the distance between 2 points (only in 3D).
Now if we will use Dijkstra's algorithm the output we will get would be the cost to travel from S to each point in the graph (we are only interested in the distance to points in group A).
So since the cost is 0 to each point b in B and S is only connected to points in B so the road to any point a in A must include a node in B (actually exactly one since the shortest distance between to points is a single line).
I am not sure if this will fasten your code but as far as I know, a way to solve this problem without calculating all distances does not exist and this algorithm is the best time complexity one could hope for.
take a look at this generic 3D data structure:
https://github.com/m4nh/skimap_ros
it has a very fast RadiusSearch feature just ready to be used. This solution (similar to Octree but faster) avoids to you to create the Regular Grid first (you don't have to fix MAX/MIN size along each axis) and you save a lot of memory
I want to create a polynomial with given coefficients. This seems very simple but what I have found till now did not appear to be the thing I desired.
For example in such an environment;
n = 11
K = GF(4,'a')
R = PolynomialRing(GF(4,'a'),"x")
x = R.gen()
a = K.gen()
v = [1,a,0,0,1,1,1,a,a,0,1]
Given a list/vector v of length n (I will set this n and v at the begining), I want to get the polynomial v(x) as v[i]*x^i.
(Actually after that I am going to build the quotient ring GF(4,'a')[x] /< x^n-v(x) > after getting this v(x) from above) then I will say;
S = R.quotient(x^n-v(x), 'y')
y = S.gen()
But I couldn't write it.
This is a frequently asked question in many places so it is better to leave it here as an answer although the answer I have is so simple:
I just wrote R(v) and it gave me the polynomial:
sage
n = 11
K = GF(4,'a')
R = PolynomialRing(GF(4,'a'),"x")
x = R.gen()
a = K.gen()
v = [1,a,0,0,1,1,1,a,a,0,1]
R(v)
x^10 + a*x^8 + a*x^7 + x^6 + x^5 + x^4 + a*x + 1
Basically (that is, ignoring the specifics of your polynomial ring) you have a list/vector v of length n and you require a polynomial which is the sum of all v[i]*x^i. Note that this sum equals the matrix product V.X where V is a one row matrix (essentially equal to the vector v) and X is a column matrix consisting of powers of x. In Maxima you could write
v: [1,a,0,0,1,1,1,a,a,0,1]$
n: length(v)$
V: matrix(v)$
X: genmatrix(lambda([i,j], x^(i-1)), n, 1)$
V.X;
The output is
x^10+ax^8+ax^7+x^6+x^5+x^4+a*x+1
I've just been working though converting some MATLAB scripts to work in R, however having never used MATLAB in my life, and not exactly being an expert on R I'm having some trouble.
Edit: It's a script I was given designed to correct temperature measurements for lag generated by insulation mass effects. My understanding is that It looks at the rate of change of the temperature and attempts to adjust for errors generated by the response time of the sensor. Unfortunately there is no literature available to me to give me an indication of the numbers i am expecting from the function, and the only way to find out will be to experimentally test it at a later date.
the original script:
function [Tc, dT] = CTD_TempTimelagCorrection(T0,Tau,t)
N1 = Tau/t;
Tc = T0;
N = 3;
for j=ceil(N/2):numel(T0)-ceil(N/2)
A = nan(N,1);
# Compute weights
for k=1:N
A(k) = (1/N) + N1 * ((12*k - (6*(N+1))) / (N*(N^2 - 1)));
end
A = A./sum(A);
# Verify unity
if sum(A) ~= 1
disp('Error: Sum of weights is not unity');
end
Comp = nan(N,1);
# Compute components
for k=1:N
Comp(k) = A(k)*T0(j - (ceil(N/2)) + k);
end
Tc(j) = sum(Comp);
dT = Tc - T0;
end
where I've managed to get to:
CTD_TempTimelagCorrection <- function(temp,Tau,t){
## Define which equation to use based on duration of lag and frequency
## With ESM2 profiler sampling # 2hz: N1>tau/t = TRUE
N1 = Tau/t
Tc = temp
N = 3
for(i in ceiling(N/2):length(temp)-ceiling(N/2)){
A = matrix(nrow=N,ncol=1)
# Compute weights
for(k in 1:N){
A[k] = (1/N) + N1 * ((12*k - (6*(N+1))) / (N*(N^2 - 1)))
}
A = A/sum(A)
# Verify unity
if(sum(A) != 1){
print("Error: Sum of weights is not unity")
}
Comp = matrix(nrow=N,ncol=1)
# Compute components
for(k in 1:N){
Comp[k] = A[k]*temp[i - (ceiling(N/2)) + k]
}
Tc[i] = sum(Comp)
dT = Tc - temp
}
return(dT)
}
I think the problem is the Comp[k] line, could someone point out what I've done wrong? I'm not sure I can select the elements of the array in such a way.
by the way, Tau = 1, t = 0.5 and temp (or T0) will be a vector.
Thanks
edit: apparently my description is too brief in explaining my code samples, not really sure what more I could write that would be relevant and not just wasting peoples time. Is this enough Mr Filter?
The error is as follows:
Error in Comp[k] = A[k] * temp[i - (ceiling(N/2)) + k] :
replacement has length zero
In addition: Warning message:
In Comp[k] = A[k] * temp[i - (ceiling(N/2)) + k] :
number of items to replace is not a multiple of replacement length
If you write print(i - (ceiling(N/2)) + k) before that line, you will see that you are using incorrect indices for temp[i - (ceiling(N/2)) + k], which means that nothing is returned to be inserted into Comp[k]. I assume this problem is due to Matlab allowing the use of 0 as an index and not R, and the way negative indices are handled (they don't work the same in both languages). You need to implement a fix to return the correct indices.
how can i calculate the polynomial that has the tangent lines (1) y = x where x = 1, and (2) y = 1 where x = 365
I realize this may not be the proper forum but I figured somebody here could answer this in jiffy.
Also, I am not looking for an algorithm to answer this. I'd just like like to see the process.
Thanks.
I guess I should have mentioned that i'm writing an algorithm for scaling the y-axis of flotr graph
The specification of the curve can be expressed as four constraints:
y(1) = 1, y'(1) = 1 => tangent is (y=x) when x=1
y(365) = 1, y'(365) = 0 => tangent is (y=1) when x=365
We therefore need a family of curves with at least four degrees of freedom to match these constraints; the simplest type of polynomial is a cubic,
y = a*x^3 + b*x^2 + c*x + d
y' = 3*a*x^2 + 2*b*x + c
and the constraints give the following equations for the parameters:
a + b + c + d = 1
3*a + 2*b + c = 1
48627125*a + 133225*b + 365*c + d = 1
399675*a + 730*b + c = 0
I'm too old and too lazy to solve these myself, so I googled a linear equation solver to give the answer:
a = 1/132496, b = -731/132496, c = 133955/132496, d = -729/132496
I will post this type of question in mathoverflow.net next time. thanks
my solution in javascript was to adapt the equation of a circle:
var radius = Math.pow((2*Math.pow(365, 2)), 1/2);
var t = 365; //offset
this.tMax = (Math.pow(Math.pow(r, 2) - Math.pow(x, 2), 1/2) - t) * (t / (r - t)) + 1;
the above equation has the above specified asymptotes. it is part of a step polynomial for scaling an axis for a flotr graph.
well, you are missing data (you need another point to determine the polynomial)
a*(x-1)^2+b*(x-1)+c=y-1
a*(x-365)^2+b*(x-365)+c=y-1
you can solve the exact answer for b
but A depends on C (or vv)
and your question is off topic anyways, and you need to revise your algebra