我有一个向量u
和一个带有单位单位的t
,我希望du
的单位为typeof(oneunit(u)/oneunit(t))
。我想找到一个通用的代码行,它构造一个匹配输入的SArray
或MArray
输出。我尝试过几个案例:
copy(u)
与单位不匹配。u/oneunit(t)
和u./oneunit(t)
都会创建SArray
s,即使u <: MArray
也是如此。similar
始终会创建一个可变类型,因此它始终会创建MArray
我是否需要直接使用构造函数(这会很痛苦,因为它会在其他通用代码中添加一个奇怪的分支,但如果这是答案就没问题了?)
简单转换不适用于MArray
s
u = @MArray [1u"g",2u"g",3u"g"]
t = 1u"s"
convert(typeof(u),u/t)
DimensionError: g and 1.0 g s^-1 are not dimensionally compatible.
虽然similar
没有希望:
u = @SArray [1u"g",2u"g",3u"g"]
similar(u)
3-element MVector{3,Quantity{Int64, Dimensions:{}, Units:{g}}}:
72559480 g
581132080 g
29791 g
答案 0 :(得分:2)
如何:
static_similar(s, v) =
( isimmutable(s) ? StaticArrays.mutable_similar_type :
StaticArrays.default_similar_type)(eltype(v),
Size(s), StaticArrays.length_val(s) )(v)
,并提供:
julia> u = @MArray [1u"g",2u"g",3u"g"];
julia> s = @SArray [1u"g",2u"g",3u"g"];
julia> static_similar(u,u./oneunit(t))
3-element SVector{3,Quantity{Float64, Dimensions:{ ^-1}, Units:{g s^-1}}}:
1.0 g s^-1
2.0 g s^-1
3.0 g s^-1
julia> static_similar(s,s./oneunit(t))
3-element MVector{3,Quantity{Float64, Dimensions:{ ^-1}, Units:{g s^-1}}}:
1.0 g s^-1
2.0 g s^-1
3.0 g s^-1
相关功能在StaticArrays/src/abstractarray.jl
中定义。特别注意评论:https://github.com/JuliaArrays/StaticArrays.jl/blob/715fefe58bef7ef1d9b2e693d3468d4fd585e11f/src/abstractarray.jl#L60-L62
答案 1 :(得分:1)
很棒的问题!
基本上,作为静态数组用户,我总是使用SArray
和函数编程方法。 (当我需要管理内存时,我可以使用Array{SArray{...}}
或其他内容,并替换外部Array
的元素。
可能不是您正在寻找的答案,但我倾向于放松关于操作返回SArray
并且只是学会完全替换SArray
这一事实。在大多数情况下,这比摆弄MArray
要快,因为LLVM自然会调用堆栈变量的SIMD指令,而堆分配的MArray
操作则不会。
您是否期望分区等操作能够保留(或不)变异的能力?
编辑:是的,使用构造函数或convert
完全是一种可行的方法。