2012-01-02 3 views
2

제 질문은 무한대 반환에서 NaN 반환으로 변경되었습니다. FFT가 항상 Infinity를 반환하면 (http://gerrybeauregard.wordpress.com/2011/04/01/an-fft-in-c/#comment-196) 도움이 될 수 있습니다. 그래서 C#은 네거티브 숫자의 제곱근을 얻으려고하기 때문에 NaN을 반환한다고 생각합니다. 제곱근을 얻기 전에 두 숫자를 모두 제곱하고 있기 때문에 숫자가 음수가 아니어야합니다. 양). 그러나 반환 된 숫자는 음수입니다. re * re와 im * im을 얻기 위해 여러 변수를 사용하는 것이 비효율적이며 두 결과가 합쳐지기 때문에 비효율적 이었지만 결과는 부정적인 결과를 낳았습니다. 수학 .Abs도 좋지 않았습니다. FFT 클래스 작성자 (위의 링크 참조)에 연락하여 다음 답장을 기다리고 있습니다. 나는 전에 내가했던 AS3 버전에서 아래의 코드 중 일부를 사용했다. 만약 내가 여기에 하나를 얻으려면 내가 클래스 창조자에게서 대답을 얻으면, 나는 그것을 게시 할 것이다. 어떤 통찰력이 가장 도움이되며 지금까지 나를 도왔던 모든 사람들에게 감사드립니다. 나는 AS3 프로그래머가 C#으로 가고있다. (훨씬 더 유능하기 때문이다.) 그래서 나는 내 초능력에서 단순한 것을 놓친 것이 가능하다. 나는 Unity를 사용하고 있습니다.Decibel 대 진폭은 항상 C에서 NaN을 반환합니다. #

private const uint LOGN = 11; // Log2 FFT Length 

    private const uint N = 1 << (int)LOGN; // FFT Length 

    private const uint BUF_LEN = N; // Audio buffer length 

    public FFT2 fft; // FFT Object 

    private double[] tempIm = new double[N]; // Temporary Imaginary Number array 

    private double[] m_mag = new double[N/2]; // Magnitude array 

    private double[] m_win = new double[N]; // Hanning Window 

    private int fftCount = 0; // How many times the FFT has been performed 

    private double SCALE = (double)20/System.Math.Log(10); // used to convert magnitude from FFT to usable dB 

    private double MIN_VALUE = (double)System.Double.MinValue; 

...

// Hanning analysis window 
    for (int i = 0; i < N; i++) // for i < 2048 
     m_win[i] = (4.0/N) * 0.5*(1-Mathf.Cos(2*Mathf.PI*i/N)); // Hanning Vector [1] = 1/4595889085.750801 

...

// Perform FFT 
fft.run(tempRe, tempIm); 

fftCount++; 

// Convert from Decibel to Magnitude 
for (int i = 0; i < N/2; i++) { 

double re = tempRe[i]; // get the Real FFT Number at position i 
double im = tempIm[i]; // get the Imaginary FFT Number at position i 

m_mag[i] = Math.Sqrt(re * re + im * im); // Convert magnitude to decibels 

m_mag[i] = SCALE * Math.Log(m_mag[i] + MIN_VALUE); 

if (fftCount == 50 && i == 400) print ("dB @ 399: " + m_mag[399]); 
} 

선행 코드 인쇄 :

dB @ 400: NaN 

-5.56725062513722E+33 

감사합니다!

+0

[this sample] (http://accord-net.origo.ethz.ch/wiki/sample_applications#Fourier) – oleksii

+0

디버거에서 다음 줄을 확인하십시오.'m_mag [i] = 10 * Mathf.Log10 ((float) ((re * re) + (im * im)))));) 실제와 가상의 값은 무엇입니까? – oleksii

+0

고마워요! 나는 지금 그 틀을보고있다. 실제 Fourier 소스에 대한 링크는 없으며 응용 프로그램의 사진 만 있습니다. 어떠한 이유로 든 사이트의 다운로드 섹션에 행운이 없거나, 다른 것들이 호스팅되는 CodeProject에 없습니다. 디버깅 후 re 및 im은 각 인덱스의 두 배열에 대해 사용 가능한 숫자를 반환합니다. 이 수학을 계속 확인하지만 기본적으로 정확히 내가 AS3 버전에서 사용했던 것입니다. 수식을 decibel하는 정도는 내가 확인하는 모든 소스가 권장하는 것입니다. –

답변

1

MIN_VALUE을 가능한 가장 작은 배정도 숫자 인 System.Double.MinValue으로 정의했습니다. System.Double.MaxValue 또는 양의 무한대 이외의 값을 추가하면 부정적인 결과가 나타납니다. 음수의 대수를 취하면 NaN이됩니다.

MIN_VALUE이 (가) 작은 양수가되도록 추측하고 있습니다. C#에서는 System.Double.Epsilon을 사용합니다. (나는 알고있다. ... 그렇게 부르면 안된다 ...)

1e-100과 같은 다른 작은 값도 사용할 수있다.

+0

고마워요! 나는 우리가 동시에 그 해답을 발견했다고 생각한다 : 나는 지금 또 다른 문제를 겪고있다. 그러나 FFT 클래스 자체와 함께 있다고 생각한다. –

0

for (int i = 0; i < tempRe.Length; i ++) tempRe [i] = m_win [i];

곱셈을 사용하면 원하지 않는 한 항상 0이됩니다.

+0

방금 ​​해닝 창 코드를 맨 위에 추가했습니다. 창을 적용하기 위해서는 그것을 곱해야합니다. Window로 설정하면 실제 샘플에서 FFT를 수행하지 않습니다. 디버깅은 tempRe가 FFT 전에 사용 가능한 데이터를 포함하고 있음을 보여줍니다. –

+0

다른 문제는 해결했지만이 문제와 관련된 새로운 문제가 있습니다. 모든 도움에 감사드립니다. 위의 질문을 업데이트했습니다. –

0

답변을 찾았습니다! 그래서 C++, AS3 및 다른 언어와 달리 C#은 음의 최소값을가집니다.

System.Double.MIN_VALUE = -1.7976931348623157E+308; 

네거티브의 제곱근을 얻으면 NaN 오류가 발생합니다. 자세한 내용은 (http://www.codeproject.com/KB/cs/numprogrammingcs.aspx)을 참조하십시오. 나는 정확한 dB 수치를 얻는 데 어려움을 겪고 있지만 연구하고 내가 찾을 수있는 것을 봅니다.

관련 문제