Sza*_*lcs 8 wolfram-mathematica
我想知道这是一个错误还是记录在案的行为?
f1 = Function[v,
Do[If[v[[i]] < 0, Return[v[[i]]]], {i, 1, Length[v]}]]
c1 = Compile[{{v, _Integer, 1}},
Do[If[v[[i]] < 0, Return[v[[i]]]], {i, 1, Length[v]}]]
Run Code Online (Sandbox Code Playgroud)
将它们应用于不包含负数的列表时,我们会得到不同的结果:
In[66]:= Through[{f1, c1}[{1, 2, 3}]]
Out[66]= {Null, 3}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译一个简短的函数(实际上是它的修改版本)时,这会导致错误.
Do 单独没有显示问题:
c2 = Compile[{}, Do[i, {i, 5}]]
c2[] (* returns nothing, as expected *)
Run Code Online (Sandbox Code Playgroud)
正如 @Pillsy 和 @Leonid 的答案中所指出的,问题在于原始函数有时返回Null,有时返回整数。相反,编译后的函数始终返回一个整数。在 V8 中,我们可以使用以下命令看到这一点CompilePrint:
Needs["CompiledFunctionTools`"]
CompilePrint @
Compile[{{v,_Integer,1}},Do[If[v[[i]]<0,Return[v[[i]]]],{i,1,Length[v]}]]
Run Code Online (Sandbox Code Playgroud)
在 V8.0.4 下,产生以下结果:
1 argument
1 Boolean register
6 Integer registers
1 Tensor register
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
T(I1)0 = A1
I3 = 0
I0 = 1
Result = I5
1 I2 = Length[ T(I1)0]
2 I4 = I3
3 goto 10
4 I5 = Part[ T(I1)0, I4]
5 B0 = I5 < I3
6 if[ !B0] goto 10
7 I5 = Part[ T(I1)0, I4]
8 goto 11
9 goto 10
10 if[ ++ I4 < I2] goto 4
11 goto 12
12 Return
Run Code Online (Sandbox Code Playgroud)
我们可以看到编译函数的结果就是整数寄存器中的结果I5。按照反编译指令的流程,我们看到如果没有匹配,那么I5最终将包含列表的最后一个元素。
编译器的行为可能会在 Mathematica 版本之间发生变化。我认为有理由认为,在返回结果类型不明确的情况下,编译器至少应该发出警告。
| 归档时间: |
|
| 查看次数: |
382 次 |
| 最近记录: |