在近似的树皮尺度上获得等距间隔

时间:2012-10-09 19:46:26

标签: algorithm matlab math octave numerical

维基百科说我们可以用等式近似巴克规模:

b(f) = 13*atan(0.00076*f)+3.5*atan(power(f/7500,2))

如何在Bark标度上将频谱划分为相同长度的n区间(区间分割点在Bark标度上是等距的)?

最好的方法是分析反函数(用x的函数表达y)。我试图在纸上做但却失败了。 WolframAlpha搜索栏也无法做到。我尝试了Octave finverse函数,但是我收到了错误。

Octave说(更简单的例子):

octave:2> x = sym('x');
octave:3> finverse(2*x)
error: `finverse' undefined near line 3 column 1

这是来自Matlab的finverse描述:http://www.mathworks.com/help/symbolic/finverse.html

也可以通过数字方式来做到这一点。我可以想象你只是从平均分割y轴开始,通过二分搜索搜索理想的除法。但也许有一些现有的工具可以做到这一点?

4 个答案:

答案 0 :(得分:1)

此功能无法通过分析反转。你必须使用一些数字程序。二进制搜索会很好,但有更有效的方法可以做这些事情:查看root-finding algorithms。对于每个频率间隔端点b(f) = f_n,您可以将选择的算法应用于等式f_n

答案 1 :(得分:1)

你需要在数值上求解这个方程(没有解析反函数)。设置等间距b的值并求解等式以找到各种f。 Bissection有点慢,但布伦特的方法是一个非常好的选择。见http://en.wikipedia.org/wiki/Brent%27s_method

答案 2 :(得分:1)

我最终决定不使用Bark值近似,而是使用关键波段中心的理想值(为n=1..24定义)。我用gnuplot绘制它们,并在同一图表上绘制了任意选择的密度较大的点的值(对于所需的n>24)。我调整了Hz中的点值,直到两条曲线大致相同。

当然 rpsmi David Zaslavsky 的答案更为通用和可扩展。

答案 3 :(得分:1)

就像你知道的那样,在(比方说)octave中实现rpsmi或David Zaslavsky的答案,你会做这样的事情:

global x0 = 0.

function res = b(f)
   global x0
   res = 13*atan(0.00076*f)+3.5*atan(power(f/7500,2)) - x0
end

function [intervals, barks] = barkintervals(left, right, n)
    global x0
    intervals = linspace(left, right, n);
    barks     = intervals;
    for i = 1:n
        x0 = intervals(i);
         # 125*x0 is just a crude guess starting point given the values
        [barks(i), fval, info] = fsolve('b', 125*x0);
    endfor
end

然后像这样运行:

octave:1> barks
octave:2> [i,bx] = barkintervals(0, 10, 10)
[... lots of output from fsolve deleted...]
i =

 Columns 1 through 8:

    0.00000    1.11111    2.22222    3.33333    4.44444    5.55556    6.66667    7.77778

 Columns 9 and 10:

    8.88889   10.00000

bx =

 Columns 1 through 6:

   0.0000e+00   1.1266e+02   2.2681e+02   3.4418e+02   4.6668e+02   5.9653e+02

 Columns 7 through 10:

   7.3639e+02   8.8960e+02   1.0605e+03   1.2549e+03