- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在用头撞墙,试图在 julia 中使用静态数组。
https://github.com/JuliaArrays/StaticArrays.jl
它们很快,但更新它们很痛苦。这并不奇怪,它们本来就是不可变的!
但是我一直建议我使用静态数组,即使我必须更新它们。就我而言,静态数组很小,只有 3 个长度,我有一个向量,但我一次只更新 1 个长度为 3 的 SVector。
选项 1
有一个非常简洁的包叫 Setfield
这允许您在 Julia 中对 SVector 进行就地更新。
https://github.com/jw3126/Setfield.jl
问题...它更新了本地副本。因此,如果您在嵌套函数中,它会更新本地副本。因此它带有一些簿记,因为您必须就地更新本地副本,然后 return
复制并更新感兴趣的实际数组。您无法传入所需的数组并就地更新它,至少,我无法弄清楚!现在,我不介意簿记,但我觉得更新本地副本,然后返回值,更新另一个本地副本,然后返回值并最终更新实际数组必须伴随速度损失。我可能是错的。
选项 2
让我感到困扰的是,为了更新静态数组,我必须exampleSVector::SVector{3,Float64}
<-- 只是为了说明它的类型和大小exampleSVector = [value1, value2, value3]
即使它在函数内部,这也会更新所需的数组,这是很好的目标,但是如果您在函数内部执行此操作,则会创建一个临时数组。这让我很伤心,因为我的函数处于一个被调用 4+ 百万次的循环中,所以这会产生大量的分配并减慢速度。
我如何更新 SVector
对于不创建临时数组的选项 2 场景?
对于选项 1 方案,我可以更新感兴趣的实际数组而不是本地副本吗?
如果这需要一个简单的示例代码,请在评论中说明,我会制作一个。我的想法是没有一个是可以回答的,但如果需要我会做一个。
编辑:
MCVE 代码 - 选项 1 有效,选项 2 无效。
using Setfield
using StaticArrays
struct Keep
dreaming::Vector{SVector{3,Float64}}
end
function INNER!(vec::SVector{3,Float64},pre::SVector{3,Float64})
# pretend series of calculations
for i = 1:3 # illustrate use of Setfield (used in real code for this)
pre = @set pre[i] = rand() * i * 1000
end
# more pretend calculations
x = 25.0 # assume more calculations equals x
################## OPTION 1 ########################
vec = @set vec = x * [ pre[1], pre[2], pre[3] ] # UNCOMMENT FOR FOR OPTION 1
return vec # UNCOMMENT FOR FOR OPTION 1
################## OPTION 2 ########################
#vec = x * [ pre[1], pre[2], pre[3] ] # UNCOMMENT FOR FOR OPTION 2
#nothing # UNCOMMENT FOR FOR OPTION 2
end
function OUTER!(always::Keep)
preAllocate = SVector{3}(0.0,0.0,0.0)
for i=1:length(always.dreaming)
always.dreaming[i] = INNER!(always.dreaming[i], preAllocate) # UNCOMMENT FOR FOR OPTION 1
#INNER!(always.dreaming[i], preAllocate) # UNCOMMENT FOR FOR OPTION 2
end
end
code = Keep([zero(SVector{3}) for i=1:5])
OUTER!(code)
println(code.dreaming)
最佳答案
我希望我已经正确理解了你的问题。像这样的 MWE 有点困难,它做了很多大部分是多余的和有点困惑的事情。
这里似乎有两种替代解释:要么你真的需要更新('变异')SVector
,但您的 MWE 未能证明原因。或者,您已经说服自己需要变异,但实际上并没有。
我决定专注于备选方案 2:你真的不需要“变异”。从这个角度重写你的代码可以大大简化它。
我找不到任何理由让你在这里改变任何静态向量,所以我只是删除了它。 INNER!
的行为输入功能非常困惑。您提供了两个输入但不使用其中任何一个,因此我删除了这些输入。
function inner()
pre = @SVector [rand() * 1000i for i in 1:3]
x = 25
return pre .* x
end
function outer!(always::Keep)
always.dreaming .= inner.() # notice the dot in inner.()
end
code = Keep([zero(SVector{3}) for i in 1:5])
outer!(code)
display(code.dreaming)
SVector
的原因可能有一些合理的原因。 .在这种情况下,您可以使用
setindex
StaticArrays 的方法,你不需要 Setfield.jl:
julia> v = rand(SVector{3})
3-element SArray{Tuple{3},Float64,1,3}:
0.4730258499237898
0.23658547518737905
0.9140206579322541
julia> v = setindex(v, -3.1, 2)
3-element SArray{Tuple{3},Float64,1,3}:
0.4730258499237898
-3.1
0.9140206579322541
setindex
(没有
!
)不会改变它的输入,而是创建一个改变了一个索引值的新实例。
Keep
似乎完全没有必要和分心。只需做一个
Vector
的
SVector
s 并显示您想用它做什么。
SVector
的向量。 s。你不能真正改变
SVector
s,但您可以使用方便的语法替换它们,
setindex
,您可以在其中保留一些元素并更改其他一些元素:
oldvec = [zero(SVector{3}) for _ in 1:5]
replacevec = [rand(SVector{3}) for _ in 1:5]
oldvec
的每个元素的第二个元素与
replacevec
中的对应一个.首先是单线:
oldvec .= setindex.(oldvec, getindex.(replacevec, 2), 2)
for i in eachindex(oldvec, replacevec)
@inbounds oldvec[i] = setindex(oldvec[i], replacevec[i][2], 2)
end
关于arrays - 在嵌套函数中更新静态数组而不创建临时数组? < Julia >,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54726967/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!