title: Float to Double conversion for android
body: <p>OK, so this should be simple... But I still can't figure it out. I am writing a program in java for Android to take the fft of a float array. On the complex frequency spectrum returned I extract the real and imaginary components so I can calculate some parameters such as magnitude and phase. The problem is the libgdx fft transform I am using uses float, however most of the Math class operations use double. So that means I need to convert float to double.
  It seems to work fine on the Real component of the fft, however with the imaginary I get precision errors, or rather I get for one frequency bin I get an imaginary float value of 45.188522 however, when I convert to double it changes to -45.188522.</p>
  
  <pre><code>   fft.forward(array);
     fft_cpx=fft.getSpectrum();
     tmpi = fft.getImaginaryPart();
     tmpr = fft.getRealPart();
     for(int i=0;i&lt;array.length/2;i++)
     {
         real[i] = (double) tmpr[i];
         imag[i] = (double) tmpi[i];  // THIS CONVERSION
         mag[i] = (float)Math.sqrt((real[i]*real[i]) + (imag[i]*imag[i]));
         phase[i] = (float) ((float) Math.atan2(imag[i], real[i]));
     }
  </code></pre>
  
  <p>I am aware and have tried the android FloatMath class, however there is no atan2 implemented so I am forced to convert to double regardless. </p>
  
  <p>I have also tried a few different conversions like:</p>
  
  <pre><code> imag[i] = tmpi[i];
   imag[i] = Double.parseDouble(Float.toString(tmpi[i])); // Of course you loose accuracy
  </code></pre>
  
  <p>But all still return a -45.18852 instead of 45.18852</p>
  
  <p>^^^^^ ORIGINAL ^^^^^^ </p>
  
  <p>More Detail:</p>
  
  <p>Below is my src code and usage for those interested.</p>
  
  <p>Ok, I am using Ubuntu 10.10 with eclipse JDK, Version: Helios Service Release 2
  Android SDK: The latest r10 from <a href="http://developer.android.com/sdk/index.html" rel="nofollow">android developers</a>.
  I am compiling for android 1.6, API level 4. 
  I am using libgdx for the fft you can get it here, <a href="http://code.google.com/p/libgdx/wiki/Building" rel="nofollow">Libgdx</a> and ensure you add the gdx.jar to your libs and added to your build path libraries. If you create a new project either with the same or new activity for android 1.6, set up a AVD, the one I have set up has the following support (included for completeness) :</p>
  
  <pre><code>SD Card yes
  Accellerometer yes
  DPas Support yes
  Abstracted LCD Density 240
  Audio Playback Support yes 
  Max VM Application heap size 24
  camera support no
  Touch Screen support yes
  </code></pre>
  
  <p>Here is my src code: </p>
  
  <pre><code>package com.spec.example;
  import android.app.Activity;
  import android.os.Bundle;
  import com.badlogic.gdx.audio.analysis.FFT;
  import java.lang.String;
  import android.util.FloatMath;
  import android.widget.TextView;
  
  public class spectrogram extends Activity {
  /** Called when the activity is first created. */
  float[] array = {1, 6, 1, 4, 5, 0, 8, 7, 8, 6, 1,0, 5 ,6, 1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  float[] array_hat,res=new float[array.length/2];
  float[] fft_cpx,tmpr,tmpi,mod_spec =new float[array.length/2];
  float[] real_mod = new float[array.length], imag_mod = new float[array.length];
  double[] real = new double[array.length], imag= new double[array.length];
  double[] mag = new double[array.length] ,phase = new double[array.length];
  int n;
  float tmp_val;
  String strings;
  FFT fft = new FFT(32, 8000);
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      TextView tv = new TextView(this);
  
     fft.forward(array);
     fft_cpx=fft.getSpectrum();
     tmpi = fft.getImaginaryPart();
     tmpr = fft.getRealPart();
     for(int i=0;i&lt;array.length;i++)
     {
         real[i] = (double) tmpr[i];   // This works well
         imag[i] = (double) tmpi[i];  // However this is creates a problem
         //mag[i] = FloatMath.sqrt((tmpr[i]*tmpr[i]) + (tmpi[i]*tmpi[i]));   //using FloatMath android class (works fine)
         mag[i] = Math.sqrt((real[i]*real[i]) + (imag[i]*imag[i]));
         phase[i]=Math.atan2(imag[i],real[i]);
  
         /****Reconstruction****/        
         real_mod[i] = (float) (mag[i] * Math.cos(phase[i]));
         imag_mod[i] = (float) (mag[i] * Math.sin(phase[i]));
  
     }
  
     fft.inverse(real_mod,tmpi,res);// inverse fft to reconstruct original array if input = output It works as it is, however it is using the input imaginary, not imag_mod
     strings=String.valueOf(tmpi[1]); // Just printing the second imaginary element Calculated using: |X|e^(j*phaseofX) = |X|(cos(X) + jsin(X))
     //strings=String.valueOf(imag_mod[1]); // Just printing the second imaginary element (Original returned from fft.getImaginary())
      //this ^^ is the one which returns a -ve (Uncomment to test)
     tv.setText(strings);
     setContentView(tv);
  
      }
    }
  </code></pre>
  
  <p>I am new to android development and java, so please be patient with me if the answer seems obvious or my syntax seems odd. Hopefully someone work it out... </p>