【问题标题】:Implementing LAPACK routine hseqr() in Julia (creating wrapper error: no method matching Array{Float64,1}(::Int64))在 Julia 中实现 LAPACK 例程 hseqr()(创建包装错误:没有方法匹配 Array{Float64,1}(::Int64))
【发布时间】:2020-04-23 18:27:16
【问题描述】:

我正在尝试实现从 LAPACK(link:http://www.netlib.org/lapack/explore-html/da/dba/group__double_o_t_h_e_rcomputational_gacb35e85b362ce8ccf9d653cc3f8fb89c.html#gacb35e85b362ce8ccf9d653cc3f8fb89c) 到 Julia 的 hseqr() 例程,但是当我调用该函数时出现此错误:

error: no method matching Array{Float64,1}(::Int64)

这是我的代码:

for (hseqr, elty) in
    ((:dhseqr_,:Float64),
    (:shseqr_,:Float32))
    @eval begin
        """
     JOB    
          JOB is CHARACTER*1
           = 'E':  compute eigenvalues only;
           = 'S':  compute eigenvalues and the Schur form T.
    COMPZ   
          COMPZ is CHARACTER*1
           = 'N':  no Schur vectors are computed;
           = 'I':  Z is initialized to the unit matrix and the matrix Z
                   of Schur vectors of H is returned;
           = 'V':  Z must contain an orthogonal matrix Q on entry, and
                   the product Q*Z is returned.
        """
        function hseqr!(job::Char,compz::Char,ilo::Integer,ihi::Integer,H::StridedMatrix{$elty}, Z::StridedMatrix{$elty})
            N=size(H,1)
            ldh=size(H,1)
            ldz=size(Z,1)
            work = Vector{$elty}(1)
            lwork = BlasInt(-1)
            info = Ref{BlasInt}()
            for i = 1:2  # first call returns lwork as work[1]
                ccall((@blasfunc($hseqr), liblapack),Void,
                    (Ref{UInt8},Ref{UInt8}, Ref{BlasInt},Ref{BlasInt},Ref{BlasInt},
                        Ptr{$elty}, Ref{BlasInt},Ptr{$elty}, Ptr{$elty}, Ptr{$elty}, 
                        Ref{BlasInt}, Ptr{BlasInt}, Ref{BlasInt}, Ref{BlasInt}),
                        job,compz, N,ilo,ihi,H,ldh,wr,wi,Z,ldz,work, 
                        lwork,info) 
                chklapackerror(info[])
                if i == 1
                    lwork = BlasInt(real(work[1]))
                    resize!(work, lwork)
                end
            end
            return wr,wi,Z
        end
    end
end
hseqr!(job::Char,compz::Char,H::StridedMatrix{},Z::StridedMatrix{}) = hseqr!(job,compz,1, size(H, 1), H,Z)

这是我的电话: hseqr!('E','N',H,Matrix{Float64}(I,5,5))(H 是维数为 5 的 Hessenberg 矩阵)。

我不确定我是否正确理解如何制作包装器,所以任何提示都会有所帮助。

【问题讨论】:

  • 也许将像您这样的 LAPACK 包装器捆绑到一个包中甚至将其集成到 Julia 本身中是有意义的。一旦您的代码可靠运行,如果您可以在 GitHub 上为此创建一个问题,那就太好了。

标签: julia linear-algebra lapack eigenvalue


【解决方案1】:

这是一个很好的例子,可以通过剥离相当多的内容来隔离问题。

如果我正确阅读了您的代码,则该行

work = Vector{$elty}(1)

Float64 作为元素类型调用,所以整个事情归结为:

julia> Vector{Float64}(1)
ERROR: MethodError: no method matching Array{Float64,1}(::Int64)

您误用了向量的构造函数。现在我不确定您要在这里做什么,但是如果您要创建一个长度为 1 的 Float64 数字向量,您可能正在寻找以下其中之一:

julia> Array{Float64}(undef, 1)
1-element Array{Float64,1}:
 6.9274314537094e-310

julia> zeros(1)
1-element Array{Float64,1}:
 0.0

请注意,第一次调用未初始化数组,即它填充了之前内存中的任何内容,因此您要确保仅在稍后实际覆盖它时才使用它。

【讨论】:

    猜你喜欢
    • 2016-06-04
    • 2022-01-24
    • 2020-07-05
    • 2023-03-27
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    相关资源
    最近更新 更多