我已经能够在所有值都是真实的cblas_sgemv中使用。但是,我无法使用cblas_cgemv而不会收到"EXC_BAD_ACCESS"错误。对于这个函数,我假设复杂部分直接出现在函数作为参数的数组中的实际部分之后是否正确?例如,如果我有一个矩阵:
1 + 2i, 3 + 4i
5 + 6i, 7 + 8i
那么它将表示为 [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0]。此外,对于任何给定的矩阵和向量,N,M,lda,incX和incY相对于其在数组中的表示应该是什么值?
完整示例:对于函数原型所在的cblas_sgemv:
func cblas_sgemv(_ __Order: CBLAS_ORDER, _ __TransA: CBLAS_TRANSPOSE, _ __M: Int32, _ __N: Int32, _ __alpha: Float, _ __A: UnsafePointer<Float>, _ __lda: Int32, _ __X: UnsafePointer<Float>, _ __incX: Int32, _ __beta: Float, _ __Y: UnsafeMutablePointer<Float>, _ __incY: Int32)
此代码有效:
let matrix: [Float] = [1.0,2.0,3.0,4.0]
let vector: [Float] = [1.0,2.0]
let matrixConverted: UnsafePointer<Float> = UnsafePointer<Float>(matrix)
let vectorConverted: UnsafePointer<Float> = UnsafePointer<Float>(vector)
let matrixSize = sqrt(Double(matrix.count)
let total: [Float] = [Float](count: Int(matrixSize), repeatedValue: 0.0)
let totalConverted: UnsafeMutablePointer<Float> = UnsafeMutablePointer<Float>(total)
cblas_sgemv(CblasRowMajor, CblasNoTrans, Int32(matrixSize), Int32(matrixSize), 1.0, matrixConverted, Int32(matrixSize), vectorConverted, 1, 0, totalConverted, 1)
答案是总共存储的。那么,使用上面的复杂矩阵和与原型cblas_cgemv函数做同样的事情会是什么样子:
func cblas_cgemv(_ __Order: CBLAS_ORDER, _ __TransA: CBLAS_TRANSPOSE, _ __M: Int32, _ __N: Int32, _ __alpha: UnsafePointer<Void>, _ __A: UnsafePointer<Void>, _ __lda: Int32, _ __X: UnsafePointer<Void>, _ __incX: Int32, _ __beta: UnsafePointer<Void>, _ __Y: UnsafeMutablePointer<Void>, _ __incY: Int32)
更多信息和参考资料可以在这里找到:https://developer.apple.com/library/prerelease/ios/documentation/Accelerate/Reference/BLAS_Ref/index.html#//apple_ref/doc/uid/TP30000414-SW55
您现有的代码有点太复杂了,并且有一个错误:
- 输入矩阵和向量可以直接传递到
cblas_sgemv()
不需要功能、matrixConverted
和vectorConverted
。 - 创建指向常量数组的可变指针
total
不允许。结果向量必须是可变的(并且 也不需要totalConverted
(。
因此,您的代码可以简化为:
let matrix: [Float] = [1.0,2.0,3.0,4.0]
let vector: [Float] = [1.0,2.0]
let matrixSize = sqrt(Double(matrix.count))
var total = [Float](count: Int(matrixSize), repeatedValue: 0.0)
cblas_sgemv(CblasRowMajor, CblasNoTrans, Int32(matrixSize), Int32(matrixSize), 1.0, matrix, Int32(matrixSize), vector, 1, 0, &total, 1)
记录了 BLAS 例程中复数的布局在<cblas.h>
:
* A note on complex data layouts:
*
* In order to allow straightforward interoperation with other libraries and
* complex types in C and C++, complex data in BLAS is passed through an opaque
* pointer (void *). The layout requirements on this complex data are that
* the real and imaginary parts are stored consecutively in memory, and have
* the alignment of the corresponding real type (float or double). The BLAS
* complex interfaces are compatible with the following types:
*
* - The C complex types, defined in <complex.h>.
* - The C++ std::complex types, defined in <complex>.
* - The LAPACK complex types, defined in <Accelerate/vecLib/clapack.h>.
* - The vDSP types DSPComplex and DSPDoubleComplex, defined in <Accelerate/vecLib/vDSP.h>.
* - An array of size two of the corresponding real type.
* - A structure containing two elements, each of the corresponding real type.
因此,要乘以
| 1 + 2i 3 + 4i | | 1 + 2i |
| | * | |
| 5 + 6i 7 + 8i | | 3 + 4i |
您可以将每个复数表示为两个浮点数连续存储的点数:
let matrix: [Float] = [1.0,2.0, 3.0,4.0, 5.0,6.0, 7.0,8.0]
let vector: [Float] = [1.0,2.0, 3.0,4.0]
let matrixSize = sqrt(Double(matrix.count/2))
var total = [Float](count: vector.count, repeatedValue: 0.0)
let alpha : [Float] = [1.0, 0.0]
let beta : [Float] = [1.0, 0.0]
cblas_cgemv(CblasRowMajor, CblasNoTrans, Int32(matrixSize), Int32(matrixSize), beta, matrix, Int32(matrixSize), vector, 1, alpha, &total, 1)
或者你可以用DSPComplex
来表示复数, COMPLEX
或__CLPK_complex
结构(它们都具有相同的布局(:
let matrix = [DSPComplex(real: 1.0, imag: 2.0), DSPComplex(real: 3.0, imag: 4.0),
DSPComplex(real: 5.0, imag: 6.0), DSPComplex(real: 7.0, imag: 8.0)]
let vector = [DSPComplex(real: 1.0, imag: 2.0), DSPComplex(real: 3.0, imag: 4.0)]
let matrixSize = sqrt(Double(matrix.count))
var total = [DSPComplex](count: Int(matrixSize), repeatedValue: DSPComplex())
var alpha = [DSPComplex(real: 1.0, imag: 0.0)]
var beta = [DSPComplex(real: 1.0, imag: 0.0)]
cblas_cgemv(CblasRowMajor, CblasNoTrans, Int32(matrixSize), Int32(matrixSize), alpha, matrix, Int32(matrixSize), vector, 1, beta, &total, 1)
在任何一种情况下,维度M
、N
等都是指复数的计数,因此它们与示例中M=N=2
的值相同实数,alpha
和beta
也是一个数组代表一个复杂的因素。