我可以在Accelerate.framework
中使用哪些函数来通过标量缩放矢量,并对矢量进行标准化?我发现一个我认为可能适用于文档中的缩放但我对它的操作感到困惑。
vDSP_vsma
Vector scalar multiply and vector add; single precision.
void vDSP_vsma (
const float *__vDSP_A,
vDSP_Stride __vDSP_I,
const float *__vDSP_B,
const float *__vDSP_C,
vDSP_Stride __vDSP_K,
float *__vDSP_D,
vDSP_Stride __vDSP_L,
vDSP_Length __vDSP_N
);
对就地矢量进行标准化的最简单方法就是这样
int n = 3;
float v[3] = {1, 2, 3};
cblas_sscal(n, 1.0 / cblas_snrm2(n, v, 1), v, 1);
你需要
#include <cblas.h>
要么
#include <vblas.h>
(或两者)。请注意,当对矢量进行操作时,其中一些函数位于“矩阵”部分。
如果要使用vDSP功能,请参阅Vector-Scalar Division部分。你可以做几件事:
vDSP_dotpr()
,sqrt()
和vDSP_vsdiv()
vDSP_dotpr()
,vrsqrte_f32()
和vDSP_vsmul()
(vrsqrte_f32()
是内置的NEON GCC,所以你需要检查你是否正在编译armv7)。vDSP_rmsqv()
,乘以sqrt(n)
和vDSP_vsdiv()
没有向量归一化函数的原因是因为vDSP中的“向量”意味着“很多东西一次”(直到4096
/ 8192
附近)并且必然是来自线性代数的“向量”。归一化1024
元素向量是没有意义的,并且用于规范化3
元素向量的快速函数不会使你的应用程序显着更快,这就是为什么没有一个。
vDSP的预期用法更像是对1024
2
-或3
-elements向量进行归一化。我可以发现一些方法来做到这一点:
vDSP_vdist()
获得长度向量,然后使用vDSP_vdiv()
。但是,对于长度大于2的向量,您必须多次使用vDSP_vdist()
。vDSP_vsq()
对所有输入,vDSP_vadd()
进行多次平方以添加所有输入,相当于vDSP_vsqrt()
或vDSP_vrsqrt()
,以及vDSP_vmul()
或vDSP_vdiv()
。写相当于vDSP_vsqrt()
或vDSP_vrsqrt()
应该不会太难。当然,如果你没有1024个向量来规范化,不要过于复杂化。
笔记:
32K
相对固定了大约十年或更长时间(它们可能在超线程CPU的虚拟核心之间共享,而一些较旧/较便宜的处理器可能有16K),所以你应该做的最多就是8192
就地就位对浮子进行操作。您可能希望减去堆栈空间,如果您正在执行多个顺序操作,您可能希望将其全部保留在缓存中; 1024
或2048
似乎非常明智,任何更多可能会收益递减。如果你关心,衡量表现......