如何使用更改的单位创建SArray / MArray?

时间:2017-10-28 01:21:41

标签: arrays julia

我有一个向量u和一个带有单位单位的t,我希望du的单位为typeof(oneunit(u)/oneunit(t))。我想找到一个通用的代码行,它构造一个匹配输入的SArrayMArray输出。我尝试过几个案例:

  1. 显然copy(u)与单位不匹配。
  2. u/oneunit(t)u./oneunit(t)都会创建SArray s,即使u <: MArray也是如此。
  3. similar始终会创建一个可变类型,因此它始终会创建MArray
  4. 我是否需要直接使用构造函数(这会很痛苦,因为它会在其他通用代码中添加一个奇怪的分支,但如果这是答案就没问题了?)

    修改

    简单转换不适用于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
    

2 个答案:

答案 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完全是一种可行的方法。