arrays - 在索引处增加 StaticVector

标签 arrays julia

我想将位置 i 处的静态数组 A 增加 x。如果它是一个可变数组,我只会执行A[i] += x。但由于它是 StaticArray,我需要创建一个新的。但是,如果我新的 A 的大小,那么我会做类似的事情

A = A + @SVector [0,0,x]

并且每个i都有一个分支。但在本例中,SVector 是用户输入,因此我只能使用类型信息提前知道。我不想让我的核心逻辑全部成为一个生成函数来处理这个问题,所以我希望有一个简单的解决方案,或者这可能需要一个 @ generated 辅助函数。

请注意,此问题相当于创建一个 @SVector,其在位置 i 处具有值 x,但其他位置为零。如果有一个简单的方法可以做到这一点,那么我的问题也解决了。

最佳答案

使用 array comprehensions 的简单方法将会是

Julia > k = 4 4

julia> @SVector [i == k? 1.0 : 0 对于 i 在 1:5] 5 元素 SVector{10,Float64}: 0.0 0.0 0.0 1.0 0.0

这是您在阅读StaticArrays.jl时可以采取的良好的第一步。自述文件的“快速入门”部分。

但是,我们在 Julia 中非常关心 type stability和通用代码, 因为:

  1. 函数的类型稳定性让编译器优化 -> 速度
  2. 可以利用multiple dispatch以强大的方式重用和扩展代码。

所以更朱利安的方法是使用

julia> 函数increment_value(A::SVector{L,T},x,k) 其中{L,T} _A = [i == k ? x : 1:L 中的 i 为零(x)] A+_A 结尾

Julia > A = @SVector [0, 0, 0, 0, 10] 5 元素 SVector{5,Int64}: 0 0 0 0 10

Julia > 增量值(A,5,2) 5 元素 SVector{5,Int64}: 0 5 0 0 10

但是,我们的最终答案应该包括一种避免额外变量分配的方法,并利用一些 compiler pipelining使用方便的 ifelse 函数:

`julia> 使用 StaticArrays、BenchmarkTools

julia> 函数increment_value(A::SVector{L,T}, x,k) 其中 {T,L} SVector(ntuple(i->ifelse(i == k, A[i]+x, A[i]), Val{L})) 结尾 increment_value(具有 1 个方法的通用函数)

Julia > a = @SVector [ 1, 2, 3, 4, 5] 5 元素 SVector{5,Int64}: 1 2 3 4 5

Julia > @benchmarkincrement_value($a,$3,$5) BenchmarkTools.试用版: 内存估计:0 字节 分配估计:0

最短时间:3.178 ns (0.00% GC) 中位时间:3.285 ns (0.00% GC) 平均时间:3.293 ns (0.00% GC) 最大时间:13.620 ns (0.00% GC) sample :10000 评估/样本:1000

关于arrays - 在索引处增加 StaticVector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47580303/

相关文章:

julia - 在 Julia 中使用 ForwardDiff 进行自动微分

java - 基本 Java 数组 - 打印递增值的 "Pyramid"

Java ArrayIndexOutOfBoundsException 仅指向一行

julia - 将 x.xxxxxxe-x*10^xx 形式的两个数字相乘不能正常工作

julia - 在 JULIA 的分布式 for 循环中写入共享数组

Julia:获取函数体

julia - 为什么加号运算符在 Julia 中被矢量化而不是除法运算符?

javascript - Three.js 使用 raycaster.intersectObject 选择 Object3D 的子级

C++ 字符串数组

c++ - 将二叉树排序为排序数组