我已经能够使用cblas_sgemv,其中所有值都是真实的。但是,如果没有获得' EXC_BAD_ACCESS'那么我就无法使用cblas_cgemv。错误。对于这个函数我是否正确地假设复杂的部分直接位于数组中的实部作为参数?例如,如果我有一个矩阵:
overlayCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
那么它将表示为[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0]。 对于任何给定的矩阵和向量,对于它在数组中的表示,N,M,lda,incX和incY应该是什么值?
完整示例: 对于cblas_sgemv,函数原型是:
1 + 2i, 3 + 4i
5 + 6i, 7 + 8i
此代码有效:
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)
答案总共存储。那么用上面的复杂矩阵和带有原型的函数cblas_cgemv做同样的事情会是什么样子:
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)
答案 0 :(得分:3)
您现有的代码有点过于复杂且有错误:
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
结构(所有结构都有。{1}}
相同的布局):
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
也是一个数组
代表一个复杂的因素。