I want to calculate the fundamental frequency with autocorrelation and I found this code:
public double calculateFFT(double[] signal)
{
final int mNumberOfFFTPoints =1024;
double[] magnitude = new double[mNumberOfFFTPoints/2];
DoubleFFT_1D fft = new DoubleFFT_1D(mNumberOfFFTPoints);
double[] fftData = new double[mNumberOfFFTPoints*2];
double max_index=-1;
double max_magnitude=-1;
final float sampleRate=44100;
double frequency;
for (int i=0;i<mNumberOfFFTPoints;i++){
fftData[2 * i] = signal[i];
fftData[2 * i + 1] = 0;
fft.complexForward(fftData);
}
for(int i = 0; i < mNumberOfFFTPoints/2; i++){
magnitude[i]=Math.sqrt((fftData[2*i] * fftData[2*i]) + (fftData[2*i + 1] * fftData[2*i + 1]));
if (max_magnitude<magnitude[i]){
max_magnitude=magnitude[i];
max_index=i;
}
}
return frequency=sampleRate*(double)max_index/(double)mNumberOfFFTPoints;
}
I analyzed that fftData before "fft.complexForward(fftData);" contains some values, but after this operation ("fft.complexForward(fftData)") contains NaN.
Why?
Can someone help me, please?
Thanks
Outputs of FFT are complex numbers. The method complex forward calculates the FFT of the fftData and puts it back in fftData. The even indices are real parts of the FFT while the odd indices are the imaginary parts. Since this code is calculating the magnitudes in the end, there's no need for a for loop. So instead of,
for (int i=0;i<mNumberOfFFTPoints;i++){
fftData[2 * i] = signal[i];
fftData[2 * i + 1] = 0;
fft.complexForward(fftData);
}
Just write :
fft.complexForward(fftData);
Related
I'm still a beginner in Java programming, and I'm using Eclipse Neon. How can I make it like that without writing the code again and again? And at the end, I want to print the final number on the screen.
Here's what I did so far:
public class othermethod {
public static void main(String[] args) {
int position = 1;
int pos = 0;
int[] zahlenlaenge = new int[100];
for (int i = 0; i < zahlenlaenge.length; i++) {
zahlenlaenge[pos] = position;
position++;
pos++;
System.out.println(pos);
}
}
}
How it should actually work:
OK, after evaluating what you're asking, I think your confusion lies in what you're doing with tracking your values.
I've taken most of your code and redone it with doubles, and renamed your array to foo for my typing purposes. I'm not sure what you're tracking, but this provides the discerning of what is sum, what is denominator, and if needed, any other values you can pretty quickly figure out where they come from.
double[] foo = new double[100]; //store the sum at any point in array
double sum = 1d; //first value
double denominator = 1d; //first denominator
for (int i = 0; i < foo.length; i++) {
foo[i] = sum; //set the sum to i (1, 2, 2.5, ...)
System.out.println(i + ":" foo[i]);
denominator *= (i + 1); //calculate the next factorial, (1, 2, 3)
sum += 1d / denominator; //calculate the sum (2, 2.5, ...)
}
You'll notice that this quickly normalizes as the 1d / denominator becomes super-tiny and is basically ignored for calculations.
I wrote some testing code which calculated Pi to whatever thing I wanted it to calculate to. It looks something like this:
public static void piCalculatorMethod1() {
int iteration = 1000000;
Real pi = Real.valueOf(0);
for (int i = 1; i < iteration + 1; i++) {
Real current = pi;
Real addendum = Real.valueOf((1/Math.pow(i, 2)));
pi = current.plus(addendum);
}
pi = pi.times(6);
pi = pi.sqrt();
System.out.println(pi.toString());
}
Quite unfortunately, the output decides it would look like this:
3.14159169866
I'm quite sure the end value is much more accurate than that, because I've seen what values they are actually adding, and that's much more accurate than that.
How do I get System.out.println to show me the whole Real instead of just the first few digits?
You may need to question your assumption about the convergence of the series. This approximation of π relies on Euler's solution to the Basel problem. Empirically, the example below finds the deviation from π2/6 for a number of iteration counts. As you can see, each order of magnitude in the iteration count adds no more than one decimal digit of accuracy.
Code:
Real PI_SQUARED_OVER_6 = Real.valueOf(Math.pow(Math.PI, 2) / 6);
for (int p = 0; p < 7; p++) {
int iterations = (int) Math.pow(10, p);
Real pi = Real.valueOf(0);
for (int i = 1; i < iterations + 1; i++) {
pi = pi.plus(Real.valueOf(1 / Math.pow(i, 2)));
}
System.out.println("10^" + p + ": " + PI_SQUARED_OVER_6.minus(pi));
}
Console:
10^0: 6.44934066848226E-1
10^1: 9.5166335681686E-2
10^2: 9.950166663334E-3
10^3: 9.99500166667E-4
10^4: 9.9995000167E-5
10^5: 9.999950000E-6
10^6: 9.99999500E-7
I've modulated a carrier frequency signal with my data using FSK like this:
double SAMPLING_TIME = 1.0 / 441000 // 44khz
int SAMPLES_PER_BIT = 136;
int ENCODING_SAMPLES_PER_BIT = SAMPLES_PER_BIT / 2;
int duration = ENCODING_SAMPLES_PER_BIT * SAMPLING_TIME;
public double[] encode(int[] bits) {
for (int i = 0; i < bits.length; i++) {
int freq = FREQUENCY_LOW;
if (bits[i] > 1)
freq = FREQUENCY_HIGH;
bitArray = generateTone(freq, duration);
message = bitArray;
}
return message;
}
private double[] generateTone(int frequency, double duration) {
int samplingRate = 1/SAMPLING_TIME; // Hz
int numberOfSamples = (int) (duration * samplingRate);
samplingTime = 2 * SAMPLING_TIME;
double[] tone = new double[numberOfSamples];
for (int i = 0; i < numberOfSamples; i++) {
double y = Math.sin(2 * Math.PI * frequency * i * SAMPLING_TIME);
tone[i] = y * CARRIER_AMPLITUDE;
}
return tone;
}
Clearly, I'm sending FREQUENCY_LOW for ZERO and FREQUENCY_HIGH for 1.
Now how do I demodulate it using FFT? I'm interested in sampling magnitudes (presence and absence) of FREQUENCY_LOW, FREQUENCY_HIGH throughout the time.
I only know basics of FFT, I was starting to write this but it doesn't make sense:
private void decode(byte[] tone, int length) {
float[] input = new float[FFT_SIZE*2]; // not sure what size? shouldn't this be buffer?
for(int i=0;i<length;i++){
input[i]=tone[i];
}
FloatFFT_1D fft = new FloatFFT_1D(FFT_SIZE);
fft.realForward(input);
}
Can someone help with code?
You can use overlapping sliding windows for your FFTs, with the window and FFT the same length as that of your data bits. Then look for magnitude peaks for your 1's and 0's in the appropriate FFT result bins across these windows. You will also need some synchronization logic for runs of 1's and 0's.
Another DSP techniques that may be less compute intensive is to do quadrature demodulation for your two frequencies and low-pass filter the result before feeding it to the synchronization logic and bit detector. Yet another possibility is two sliding Goertzel filters.
I have an input signal that I want to store in an ArrayList then convert it into Complex, which goes something like this
-0.03480425839330703
0.07910192950176387
0.7233322451735928
0.1659819820667019
and this outputs its FFT like this
0.9336118983487516
-0.7581365035668999 + 0.08688005256493803i
0.44344407521182005
-0.7581365035668999 - 0.08688005256493803i
This is in a complex structure, I want to convert this into an ArrayList type. while dropping the + 0.08688005256493803i value.
So All I need are these values
0.9336118983487516
-0.7581365035668999
0.44344407521182005
-0.7581365035668999
What is the best way of going about this?
And this is the code that I am using
public static Complex[] fft(Complex[] x) {
int N = x.length;
// base case
if (N == 1) return new Complex[] { x[0] };
// radix 2 Cooley-Tukey FFT
if (N % 2 != 0) { throw new RuntimeException("N is not a power of 2"); }
// fft of even terms
Complex[] even = new Complex[N/2];
for (int k = 0; k < N/2; k++) {
even[k] = x[2*k];
}
Complex[] q = fft(even);
// fft of odd terms
Complex[] odd = even; // reuse the array
for (int k = 0; k < N/2; k++) {
odd[k] = x[2*k + 1];
}
Complex[] r = fft(odd);
// combine
Complex[] y = new Complex[N];
for (int k = 0; k < N/2; k++) {
double kth = -2 * k * Math.PI / N;
Complex wk = new Complex(Math.cos(kth), Math.sin(kth));
y[k] = q[k].plus(wk.times(r[k]));
y[k + N/2] = q[k].minus(wk.times(r[k]));
}
return y;
}
All you want to do is just drop imaginary part of your Complex data structure.
As you not show us Complex class assume it has member for real part (e.g double real;)
To drop imaginary part just call something like complex.getRealPart(), or access complex.real (substitute with your real member name).
To compose ArrayList<Double> use the following snippet:
ArrayList<Double> list = new ArrayList<Double>();
for (Complex c : complexes) { // complexes your array of complexes returned from for fft
list.add(c.getRealpart());
}
Note: Just in case, I can be wrong, but I assume that instead of real part you need absolute value of complex number. To calculate it use:
Math.sqrt(c.getRealPart() * c.getRealPart() + c.getImPart() * c.getImPart());
From what I understand you just want the real part of the complex value. If that's the case, presumably your Complex class also has getReal() and getImaginary() (or similar) methods - so just use getReal().
I'm trying to calculate the Mean Difference average of a set of data. I have two (supposedly equivalent) formulas which calculate this, with one being more efficient (O^n) than the other (O^n2).
The problem is that while the inefficient formula gives correct output, the efficient one does not. Just by looking at both formulas I had a hunch that they weren't equivalent, but wrote it off because the derivation was made by a statician in a scientific journal. So i'm assuming the problem is my translation. Can anyone help me translate the efficient function properly?
Inefficient formula:
Inefficient formula translation (Java):
public static double calculateMeanDifference(ArrayList<Integer> valuesArrayList)
{
int valuesArrayListSize = valuesArrayList.size();
int sum = 0;
for(int i = 0; i < valuesArrayListSize; i++)
{
for(int j = 0; j < valuesArrayListSize; j++)
sum += (i != j ? Math.abs(valuesArrayList.get(i) - valuesArrayList.get(j)) : 0);
}
return new Double( (sum * 1.0)/ (valuesArrayListSize * (valuesArrayListSize - 1)));
}
Efficient derived formula:
where (sorry, don't know how to use MathML on here):
x(subscript i) = the ith order statistic of the data set
x(bar) = the mean of the data set
Efficient derived formula translation (Java):
public static double calculateMean(ArrayList<Integer> valuesArrayList)
{
double sum = 0;
int valuesArrayListSize = valuesArrayList.size();
for(int i = 0; i < valuesArrayListSize; i++)
sum += valuesArrayList.get(i);
return sum / (valuesArrayListSize * 1.0);
}
public static double calculateMeanDifference(ArrayList<Integer> valuesArrayList)
{
double sum = 0;
double mean = calculateMean(valuesArrayList);
int size = valuesArrayList.size();
double rightHandTerm = mean * size * (size + 1);
double denominator = (size * (size - 1)) / 2.0;
Collections.sort(valuesArrayList);
for(int i = 0; i < size; i++)
sum += (i * valuesArrayList.get(i) - rightHandTerm);
double meanDifference = (2 * sum) / denominator;
return meanDifference;
}
My data set consists of a collection of integers each having a value bounded by the set [0,5].
Randomly generating such sets and using the two functions on them gives different results. The inefficient one seems to be the one producing results in line with what is being measured: the absolute average difference between any two values in the set.
Can anyone tell me what's wrong with my translation?
EDIT: I created a simpler implementation that is O(N) provided the all your data has values limited to a relatively small set.The formula sticks to the methodology of the first method and thus, gives identical results to it (unlike the derived formula). If it fits your use case, I suggest people use this instead of the derived efficient formula, especially since the latter seems to give negative values when N is small).
Efficient, non-derived translation (Java):
public static double calculateMeanDifference3(ArrayList<Integer> valuesArrayList)
{
HashMap<Integer, Double> valueCountsHashMap = new HashMap<Integer, Double>();
double size = valuesArrayList.size();
for(int i = 0; i < size; i++)
{
int currentValue = valuesArrayList.get(i);
if(!valueCountsHashMap.containsKey(currentValue))
valueCountsHashMap.put(currentValue, new Double(1));
else
valueCountsHashMap.put(currentValue, valueCountsHashMap.get(currentValue)+ 1);
}
double sum = 0;
for(Map.Entry<Integer, Double> valueCountKeyValuePair : valueCountsHashMap.entrySet())
{
int currentValue = valueCountKeyValuePair.getKey();
Double currentCount = valueCountKeyValuePair.getValue();
for(Map.Entry<Integer, Double> valueCountKeyValuePair1 : valueCountsHashMap.entrySet())
{
int loopValue = valueCountKeyValuePair1.getKey();
Double loopCount = valueCountKeyValuePair1.getValue();
sum += (currentValue != loopValue ? Math.abs(currentValue - loopValue) * loopCount * currentCount : 0);
}
}
return new Double( sum/ (size * (size - 1)));
}
Your interpretation of sum += (i * valuesArrayList.get(i) - rightHandTerm); is wrong, it should be sum += i * valuesArrayList.get(i);, then after your for, double meanDifference = ((2 * sum) - rightHandTerm) / denominator;
Both equations yields about the same value, but they are not equal. Still, this should help you a little.
You subtract rightHandTerm on each iteration, so it gets [over]multiplied to N.
The big Sigma in the nominator touches only (i x_i), not the right hand term.
One more note: mean * size == sum. You don't have to divide sum by N and then remultiply it back.