我可以在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
);
答案 0 :(得分:5)
对矢量进行标准化的最简单方法就像
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
- 元素向量。我可以发现一些方法来做到这一点:
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),所以你应该做的最多就是{ {1}}用于浮点数的就地操作。您可能希望减去堆栈空间,如果您正在执行多个顺序操作,您可能希望将其全部保留在缓存中; 8192
或1024
似乎非常明智,而且可能会有更多的回报。如果你关心,衡量表现......