使用 Accelerate 框架对向量进行编码

Posted

技术标签:

【中文标题】使用 Accelerate 框架对向量进行编码【英文标题】:coding with vectors using the Accelerate framework 【发布时间】:2012-04-20 16:03:30 【问题描述】:

我第一次使用 Accelerate 框架,目标是在 ios 应用程序中实现一些矢量化代码。我从来没有尝试过在 Objective C 或 C 中处理向量方面做任何事情。有一些使用 MATLAB 的经验,我想知道使用 Accelerate 是否确实更痛苦。假设我想计算以下内容:

b = 4*(sin(a/2))^2 其中 a 和 b 是向量。

MATLAB 代码:

a = 1:4;
b = 4*(sin(a/2)).^2;

但是,在我翻阅文档后发现,使用 Accelerate 的情况完全不同。

我的 C 实现:

float a[4]  = 1,2,3,4;                        //define a
int len     = 4;
float div   = 2;                                //define 2
float a2[len];                                  //define intermediate result 1
vDSP_vsdiv(a, 1, &div, a2, 1, len);             //divide
float sinResult[len];                           //define intermediate result 2
vvsinf(sinResult, a2, &len);                    //take sine
float sqResult[len];                            //square the result
vDSP_vsq(sinResult, 1, sqResult, 1, len);       //take square
float factor = 4;                               //multiply all this by four
float b[len];                                   //define answer vector
vDSP_vsmul(sqResult, 1, &factor, b, 1, len);    //multiply

//unset all variables I didn't actually need

老实说,我不知道这里最糟糕的是什么:跟踪所有中间步骤,试图记住参数是如何在 vDSP 中相对于 VecLib 传递的(完全不同),或者需要花费大量时间来完成某件事微不足道的。

我真的希望我在这里遗漏了一些东西,并且大多数步骤都可以合并或缩短。任何关于编码资源、良好编码习惯(通过艰苦的方式学习或从书本中学习)等方面的建议都将非常受欢迎!大家都是怎么处理多行向量计算的?

【问题讨论】:

如果这个库需要 2 在一个通过指针传递的变量中来执行一个简单的除法,我会说这个库很烂。或者,您可能没有使用非向量除法。 【参考方案1】:

我想你可以这样写,但对我来说这似乎非常复杂。我更喜欢这个(特定于英特尔,但可以很容易地抽象为其他架构):

#include <Accelerate/Accelerate.h>
#include <immintrin.h>

const __m128 a = 1,2,3,4;
const __m128 sina2 = vsinf(a*_mm_set1_ps(0.5));
const __m128 b = _mm_set1_ps(4)*sina2*sina2;

另外,为了迂腐,你在这里做的不是线性代数。 线性代数只涉及线性运算(没有平方,没有像sin这样的超越运算)。


编辑:正如您所指出的,上述内容在 iOS 上开箱即用并不适用;最大的问题是没有vsinf(vMathLib 在 Accelerate on iOS 中不可用)。我没有在我的机器上安装 SDK 进行测试,但我相信类似以下的东西应该可以工作:

#include <Accelerate/Accelerate.h>

const vFloat a = 1, 2, 3, 4;
const vFloat a2 = a*(vFloat)0.5,0.5,0.5,0.5;
const int n = 4;
vFloat sina2;
vvsinf((float *)&sina2, (const float *)&a, &n);
const vFloat b = sina2*sina2*(vFloat)4,4,4,4;

不像 vMathLib 那样漂亮,但仍然相当紧凑。

一般来说,向量上的许多基本算术运算都可以工作;无需使用对任何库的调用,这就是为什么 Accelerate 不会竭尽全力干净地提供这些操作。相反,Accelerate 通常会尝试提供其他方式无法立即使用的操作。

【讨论】:

谢谢@Stephen。关于这不是线性运算,您是完全正确的。您还让我意识到我应该指出这是针对 iOS 应用程序(因此,没有英特尔芯片),所以我刚刚更新了我的问题以反映这一点。 Apple 似乎认为使用 Accelerate 框架是对向量进行操作的最佳方式,所以我想知道我的实现是否真的和它得到的一样好。【参考方案2】:

回答我自己的问题: 在 iOS 6 中,将引入 vMathLib。正如斯蒂芬澄清的那样,vMathLib 已经可以在 OSX 上使用,但在 iOS 中不可用。到现在为止。

vMathLib 提供的函数将使向量计算更容易。

【讨论】:

以上是关于使用 Accelerate 框架对向量进行编码的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 使用 Accelerate.framework 对向量进行按位异或

基于词向量使用Pytorch常规自编码器对句子进行向量表示与降维

理解编码为一个热向量的 DNA 序列的一维卷积

如何使用 vDSP / Accelerate in swift for iOS 计算向量元素的平方根

如何在 Matlab 中进行热编码? [复制]

使用apache-commons-lang3框架,对html内容进行编码和反编码