首页 > 解决方案 > Julia:创建具有值约束的 AbstractArray

问题描述

我正在开发一个 Julia 项目,该项目需要矩阵来满足 trace-one 约束。为了避免检查矩阵是否在众多函数的输入和输出处是跟踪一,我想创建一个隐含包含此约束的新数据结构。

在我的工作示例中,我定义了一个结构TraceOne,如果跟踪不等于 1,则会引发错误。

struct TraceOne
    M :: Matrix{Complex{Float64}}
    TraceOne(M) = (tr(M) == 1) ? new(M) : throw(DomainError(M, "Matrix M is not trace-one."))
end

A = TraceOne([0.1 0.5;0.3 0.9])

但是,我想避免使用键A.M返回跟踪一矩阵[0.1 0.5;0.3 0.9]

或者,我尝试创建 a struct,它是 a 的 SubType AbstractMatrix,但我无法AbstractMatrix正确初始化的值。

struct TraceOne2 <: AbstractMatrix{Complex{Float64}}
    M :: Matrix{Complex{Float64}}
    Base.size(T::TraceOne2) = size(T.M)
    Base.getindex(T::TraceOne2, I::Vararg{Int,2}) = getindex(T.M, size(T.M)...)
    Base.setindex!(T::TraceOne2, v, I::Vararg{Int,2}) = (T.M[I] = v)
    TraceOne2(M) = (tr(M) == 1) ? new(M) : throw(DomainError(M, "Matrix M is not trace-one."))
end

B = TraceOne2([0.1 0.5;0.3 0.9])

当我运行这段代码时,我发现它B[0.9 0.9;0.9 0.9]. 的所有元素B都被初始化为 的值,(2,2)即输入数组的索引。

我应该如何修改struct TraceOne2 ... end以使生成的矩阵B初始化为[0.1 0.5;0.3 0.9]

标签: structtypesconstructorinitializationjulia

解决方案


更改此功能:

Base.getindex(T::TraceOne2, I::Vararg{Int,2}) = getindex(T.M, size(T.M)...)
Base.setindex!(T::TraceOne2, v, I::Vararg{Int,2}) = (T.M[I] = v)

至:

Base.getindex(T::TraceOne2, I::Vararg{Int,2}) = getindex(T.M, I...)
Base.setindex!(T::TraceOne2, v, I::Vararg{Int,2}) = (T.M[I...] = v)

推荐阅读