为什么说函数是一个完整的黑盒? documentation 显示了 vDSP_desamp(A, I, F, C, N, P) 的伪代码:
for (n = 0; n < N; ++n)
{
sum = 0;
for (p = 0; p < P; ++p)
sum += A[n*I+p] * F[p];
C[n] = sum;
}
您还可以在任何最新的 OS X 系统上查看 /System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Headers/vDSP.h,以获取有关几乎所有 vDSP 例程的信息。它以不同的形式显示相同的东西:
for (n = 0; n < N; ++n)
C[n] = sum(A[n*I+p] * F[p], 0 <= p < P);
由此可见,每个输出值C[n] 是P 输入值从A[n*I + 0] 到A[n*I + P-1] 的函数。假设您希望下一次调用中的第一个输出值以与当前调用相同的模式继续,只需考虑当前调用中的最后一个输出值(最后一个n 将是N-1,所以最后一个输出值将是C[N-1]),下一个值是C[N]。这个C[N] 将是从A[N*I + 0] 开始的输入值的函数,即A[N*I]。
然后在下一次调用中将其与第一个输出值C[0] 匹配。 C[0] 将是从A[0*I + 0] 开始的输入值的函数,即A[0]。
因此,要从当前调用结束的地方继续进行下一次调用,您需要将值从 A[N*I] 及以上复制到 A[0] 及以上。 (这假设您通过在其中移动数据然后附加新数据来重用数组A。您还可以通过将A+N*I 作为第一个参数传递给vDSP_desamp 来继续处理数据。)
要复制的值的数量是A 在A[N*I] 之后(包括)之后的值的数量。例如,如果您在 A 中有 Number 值,您可以使用:
memcpy(A+N*I, A, (Number - N*I) * sizeof *A);
然后将新数据放在A[Number - N*I] 及以后。 (如果源和目标范围重叠,您将需要使用memmove 而不是memcpy,但这对于 vDSP_desamp 来说是不寻常的;通常连续调用共享的数据只是整个缓冲区的一小部分。)
注意:伪代码表达了操作的基本数学。出于性能原因,vDSP 例程中的实际算术可能有不同的排列方式。所以实际结果可能与直接使用伪代码计算的值存在舍入误差。