C# 这个自相关公式编程正确吗?

C# 这个自相关公式编程正确吗?,c#,math,formula,equation,C#,Math,Formula,Equation,我试图从一篇论文中实现一个基音检测算法,但是论文中的数学水平对我来说太高了一些。。。现在 我只是想确保我理解正确 我还向代码中添加了注释,该注释提出了一个让我困惑的问题 该文件可在此处找到: 公式可在第二页右上角找到。 我的代码看起来像这样 public int L = 0.1f; public float calcAutocorrelation(float[] frame) int N = frame.Length; //frame size float result

我试图从一篇论文中实现一个基音检测算法,但是论文中的数学水平对我来说太高了一些。。。现在

我只是想确保我理解正确

我还向代码中添加了注释,该注释提出了一个让我困惑的问题

该文件可在此处找到:

公式可在第二页右上角找到。

我的代码看起来像这样

public int L = 0.1f;

public float calcAutocorrelation(float[] frame)

    int N = frame.Length; //frame size

    float result = 0f;
    for (var n = 0; n < N; n++){
        result += frame[n] * frame[n + L] //in programming this is not possible as L is a float but formula says this is needed???

        /* I could cast the L to an INT type but the paper states
         * that L should range between 0 and 1, and in-code we'll
         * probably end up with L rounded to 0 most of the time.
         */

    }

    return result;
}
代码:

public int lag=1;
公共浮动相关(浮动[]帧){
浮动结果=0f;
对于(int i=0;i
问题 那么当
b_idx=7
frame[7]
185
时,
b
为什么是
NaN
? 这简直让我难以置信

以下是我这边发生的事情的截图:


编辑3

发现有关
NaN
问题的问题。 这似乎根本不是问题(我认为),可以通过使用
float.isNaN()
进行检查和更正来处理

帧被强制转换为字节数组的原因在于底层音频库
NAudio
如何处理转换

请在此处阅读:

因此,即使它显示为字节数组,在使用它时,每个值都将被正确地转换为浮点值

奇怪,但却是真的。就个人而言,根据法律,这种编码应该是非法的,jk

所以,一切似乎都在运行(我想?),我的公式实现的效果如何

那么,论文在第6页图6下说明了以下内容:

其中一个实验是将PDA应用于/a/ KayPENTAX Elemetrics语音数据库中的语音由50个组成 正常嗓音和100种功能性和器质性嗓音障碍

我记录了我自己的
/a/
元音,并对其进行了测试,这是我屏幕上绘制的内容:

论文第2页的图1a

将我的结果与论文第2页的图1a进行比较,我们可以看到非常相似的地方,但我仍然不确定我是否正确地实现了公式,因为我想要实现的公式应该类似于图1b或1c

我认为现在的问题是公式变量
I
应该在代码中的什么位置

该文件在第二页陈述了以下内容:

i=帧n内的第一个样本


所以。。。嗯…

我认为您只需要修复
for
循环中的条件,因此在上一个循环中,它不会超出范围:

public int Lag = 1;

public float CalcAutocorrelation(float[] frame)
{
    int N = frame.Length; //frame size

    float result = 0;
    for (int n = 0; n < N - Lag; n++)
        result += frame[n] * frame[n + Lag];

    return result;
}

只要在
if
中放置一个断点,看看发生了什么。这将帮助您在阵列中发现问题。修复后,您可以删除该检查并恢复上面的代码。

n+L
将截断为
n
,因为
L=0.1f
。你的意思是写
L=1.0f
?非常肯定第二页说L的范围是“从零到每帧的样本数减一”,特别是-integral@YuriFeldman啊,是的,这是正确的,我一定把它和其他东西混淆了。为什么这被认为是离题的?这完全符合主题。这是关于编程的。@meowgoesthedog我误读和曲解了这篇文章,而L的类型首先是一个INT。你说得有点对。我想写L=1;我试过这个,但我最终的结果无效,因为
frame[n]
frame[n+lag]
有时是
NaN
,我很难弄清楚原因。它们都是有效的数字,但由于某种原因,最终会变成
NaN
嗯,这一定很容易调试。我只是更新了代码来处理这个问题。我已经做了一些类似的事情,但我不认为它实际上解决了这个问题。真正的问题应该是
为什么在帧中不包含NaN的情况下首先会有NaN?
。我更新了我的问题来解释这一点。
frame[0]   : 0
frame[1]   : 0
frame[2]   : 96
frame[3]   : 185
frame[4]   : 0
frame[5]   : 0
frame[6]   : 0
frame[7]   : 185
frame[8]   : 0
frame[9]   : 0
frame[10]  : 192
frame[11]  : 184
frame[12]  : 0
frame[13]  : 0
frame[14]  : 0
frame[15]  : 184
public int lag = 1;

public float calcAutocorrelation(float[] frame){

    float result = 0f;
    for (int i = 0; i < frame.Length - lag; i++){

        float a = frame[i];
        if ( float.isNaN(a) )
            a = 0;

        int b_idx = (i + lag);
        float b = frame[b_idx];
        if ( float.isNaN(b) )
            b = 0;

        result += a * b;

    }

    return 0f - result; //just inverting the results for my purposes. Doesn't really affect the end goal.
}
public int Lag = 1;

public float CalcAutocorrelation(float[] frame)
{
    int N = frame.Length; //frame size

    float result = 0;
    for (int n = 0; n < N - Lag; n++)
        result += frame[n] * frame[n + Lag];

    return result;
}
for (int n = 0; n < N - Lag; n++)
{
    result += frame[n] * frame[n + Lag];
    if (float.IsNaN(result))
    {
        var v1 = frame[n];
        var v2 = frame[n + Lag];
    }
}