我在Accelerate框架中使用LAPACK中的dgeev
算法来计算矩阵的特征值和特征向量。这是我的代码:
var matrix:[__CLPK_doublereal] = [1,2,3,4,5,6,7,8,9]
var N = __CLPK_integer(sqrt(Double(matrix.count)))
var pivots = [__CLPK_integer](count: Int(N), repeatedValue: 0)
var workspace = [Double](count: Int(N), repeatedValue: 0.0)
var error : __CLPK_integer = 0
var lwork = __CLPK_integer(-1)
// Real parts of eigenvalues
var wr = [Double](count: Int(N), repeatedValue: 0)
// Imaginary parts of eigenvalues
var wi = [Double](count: Int(N), repeatedValue: 0)
// Left eigenvectors
var vl = [__CLPK_doublereal](count: Int(N*N), repeatedValue: 0)
// Right eigenvectors
var vr = [__CLPK_doublereal](count: Int(N*N), repeatedValue: 0)
dgeev_(UnsafeMutablePointer(("V" as NSString).UTF8String), UnsafeMutablePointer(("V" as NSString).UTF8String), &N, &matrix, &N, &wr, &wi, &vl, &N, &vr, &N, &workspace, &lwork, &error)
println("\(wr), \(vl), \(vr)")
这仅打印包含零的数组,这意味着它们不被该函数修改。我做错了什么?
更新1
我现在有了这个:
var matrix:[__CLPK_doublereal] = [1,2,3,4,5,6,7,8,9]
var N = __CLPK_integer(sqrt(Double(matrix.count)))
var pivots = [__CLPK_integer](count: Int(N), repeatedValue: 0)
var workspaceQuery = [Double](count: 1, repeatedValue: 0.0)
var error : __CLPK_integer = 0
var lwork = __CLPK_integer(-1)
// Real parts of eigenvalues
var wr = [Double](count: Int(N), repeatedValue: 0)
// Imaginary parts of eigenvalues
var wi = [Double](count: Int(N), repeatedValue: 0)
// Left eigenvectors
var vl = [__CLPK_doublereal](count: Int(N*N), repeatedValue: 0)
// Right eigenvectors
var vr = [__CLPK_doublereal](count: Int(N*N), repeatedValue: 0)
dgeev_(UnsafeMutablePointer(("V" as NSString).UTF8String), UnsafeMutablePointer(("V" as NSString).UTF8String), &N, &matrix, &N, &wr, &wi, &vl, &N, &vr, &N, &workspaceQuery, &lwork, &error)
var workspace = [Double](count: Int(workspaceQuery[0]), repeatedValue: 0.0)
dgeev_(UnsafeMutablePointer(("V" as NSString).UTF8String), UnsafeMutablePointer(("V" as NSString).UTF8String), &N, &matrix, &N, &wr, &wi, &vl, &N, &vr, &N, &workspace, &lwork, &error)
println("\(wr), \(vl), \(vr)")
仍然打印零。
答案 0 :(得分:3)
问题与您的lwork
变量有关。这应该是您提供的工作空间的大小,-1
表示您正在执行“工作区查询”:
LWORK (input) INTEGER
The dimension of the array WORK. LWORK >= max(1,3*N), and
if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N. For good
performance, LWORK must generally be larger.
If LWORK = -1, then a workspace query is assumed; the routine
only calculates the optimal size of the WORK array, returns
this value as the first entry of the WORK array, and no error
message related to LWORK is issued by XERBLA.
所以你可能想要这样的东西:
var workspaceQuery: Double = 0.0
dgeev_(UnsafeMutablePointer(("V" as NSString).UTF8String), UnsafeMutablePointer(("V" as NSString).UTF8String), &N, &matrix, &N, &wr, &wi, &vl, &N, &vr, &N, &workspaceQuery, &lwork, &error)
// prints "102.0"
println("\(workspaceQuery)")
// size workspace per the results of the query:
var workspace = [Double](count: Int(workspaceQuery), repeatedValue: 0.0)
lwork = __CLPK_integer(workspaceQuery)
dgeev_(UnsafeMutablePointer(("V" as NSString).UTF8String), UnsafeMutablePointer(("V" as NSString).UTF8String), &N, &matrix, &N, &wr, &wi, &vl, &N, &vr, &N, &workspace, &lwork, &error)
// this now prints non-zero values
println("\(wr), \(vl), \(vr)")