编译后的函数求极值。
mathematica吧
全部回复
仅看楼主
level 6
冉qx 楼主
In[5]:= f = Compile[{{x, _Real}}, Sin[x]]
Out[5]= CompiledFunction[{11, 12.2, 5468}, {
Blank[Real]}, {{3, 0, 0}, {3, 0, 1}}, {}, {0, 0, 2, 0, 0}, {{40, 1, 3,
0, 0, 3, 0, 1}, {1}},
Function[{x},
Sin[x]], Evaluate]
In[9]:= FindMaximum[f[x], {x, 1.7}]
\:6B63\:5728\:8BA1\:7B97In[9]:= CompiledFunction::cfsa: 位置 1 处的变量 x 应该是一个 machine-size real number.
Out[9]= {1., {x -> 1.5708}}
如上例,编译后的函数求极大值虽然能给出正确答案但却报错了。怎样避免这种情况?
2021年03月24日 05点03分 1
level 9
说实话我没看出来为啥会这样
Off[CompiledFunction::cfsa]
使用上述命令可以将错误信息关闭,这样就不会出现错误提示了(不建议)
或者不编译函数,直接使用函数
f[x_] = Sin[x]
FindMaximum[{f[x]}, {x, 1.7}]
也不错出现错误信息
2021年03月24日 10点03分 2
这是举一个简单的例子,实际的函数很复杂。编译是为了提高效率。
2021年03月25日 04点03分
吧务
level 10
你上次关于FindRoot问过类似的问题,原理是一样的。
https://gitee.com/rnotlnglgq/wlcnfaq/blob/master/FAQ/NestedNumericalComputation.md
2021年03月24日 16点03分 3
这个是Compile造的纯函数,NumericQ这种形式没法弄。而FindMaximum没有Evaluated这个选项。
2021年03月25日 04点03分
@冉qx 首先是可以不用纯函数,写成f[x_?NumericQ]=Compile[...][x]
2021年03月25日 04点03分
@冉qx 再就是Compile有个选项RuntimeOptions -> "EvaluateSymbolically" -> True
2021年03月25日 04点03分
@asdasd1dsadsa 怎么还是不行?
2021年03月25日 05点03分
level 6
冉qx 楼主
In[890]:= f=Compile[{{x,_Real}},Sin[x],RuntimeOptions->"EvaluateSymbolically"->True];
FindMaximum[f[x],{x,1.7}]
\:6B63\:5728\:8BA1\:7B97In[890]:= CompiledFunction::cfsa: 位置 1 处的变量 x 应该是一个 machine-size real number.
Out[891]= {1.,{x->1.5708}}
怎么还是报错了?
2021年03月25日 05点03分 4
True是算,False是不算。你应该不让它算
2021年03月25日 05点03分
@asdasd1dsadsa 行了,谢谢!
2021年03月25日 05点03分
@asdasd1dsadsa 还能看看我的关于Compile的一个问题吗?见下一层楼
2021年03月26日 04点03分
level 6
冉qx 楼主
In[80]:=
m = Table[RandomReal[{1, 100}], {i, 10}];
n = Table[RandomReal[{1, 100}], {i, 10}];
f = Compile[{{x, _Real}},
Module[{sol},
sol = Sin[x0 y0 x];
Total[Table[(sol /. {x0 -> m[[j]], y0 -> n[[j]]})^2, {j, 10}]]
], RuntimeOptions -> "EvaluateSymbolically" -> False
];
f[1]
\:6B63\:5728\:8BA1\:7B97In[80]:= CompiledFunction::cfse: 被编译表达式 x0 应该是一个 machine-size real number.
\:6B63\:5728\:8BA1\:7B97In[80]:= CompiledFunction::cfex: 在说明 1 中不能完成外部计算;继续未编译的计算.
Out[83]= 6.39718
为什么这个也报错了?
2021年03月26日 04点03分 6
level 6
冉qx 楼主
In[96]:=
m = Table[RandomReal[{1, 100}], {i, 10}];
n = Table[RandomReal[{1, 100}], {i, 10}];
f = Compile[{{x, _Real}},
Module[{sol},
sol = Sin[x0 y0 x];
Total[Table[(sol /. {x0 -> m[[j]], y0 -> n[[j]]})^2, {j, 10}]]
], {{x0, _Real}, {y0, _Real}},
RuntimeOptions -> "EvaluateSymbolically" -> False
];
f[1]
\:6B63\:5728\:8BA1\:7B97In[96]:= CompiledFunction::cfse: 被编译表达式 x0 应该是一个 machine-size real number.
\:6B63\:5728\:8BA1\:7B97In[96]:= CompiledFunction::cfex: 在说明 1 中不能完成外部计算;继续未编译的计算.
Out[99]= 3.39222
变成这个形式同样报错!
2021年03月26日 05点03分 7
EvaluateSymbolically只是当你的输入是符号表达式时不计算。你的问题在于x0 y0不是数值
2021年03月26日 08点03分
@asdasd1dsadsa 谢谢了,问题解决了!我还想问问关于函数调用次数的问题。
2021年03月26日 12点03分
level 6
冉qx 楼主
In[4]:= f[x_?NumericQ] := x^2 - 2
In[5]:= {res, data} =
Reap[FindRoot[f[x], {x, 1}, EvaluationMonitor :> Sow[x - Sqrt[2]]]]
Out[5]= {{x -> 1.41421}, {{-0.414214, 0.0857864, 0.0024531,
2.1239*10^-6, 1.59472*10^-12, 0.}}}
上面EvaluationMonitor 可以监视迭代步数,怎样才能给出函数f[x]的调用次数呢?
2021年03月26日 12点03分 8
level 6
冉qx 楼主
In[9]:= Block[{c = 0}, {FindRoot[f[x], {x, 1},
EvaluationMonitor :> c++], c}]
Out[9]= {{x -> 1.41421}, 6}
帮助文档上说的“数目计算”,这个数目指的是啥的数目
2021年03月26日 12点03分 9
就是步数啊。你要了解严格的f调用情况,可以Trace
2021年03月26日 14点03分
@asdasd1dsadsa 没用呀!
2021年03月26日 14点03分
level 6
冉qx 楼主
f[x_?NumericQ] := x^3 + x - 2
In[35]:= FindRoot[f[x] == 0, {x, 0.}] // Trace[#, f[___]] &
Out[35]= {}
2021年03月26日 14点03分 10
@asdasd1dsadsa 应该说,纯函数可以用,但是要用HoldAll或者Unevaluated来调计算次序。
2021年04月03日 03点04分
不要用纯函数。再就是要打开TraceInternal选项
2021年03月26日 16点03分
@xzcyr 我说的确实有可能带来误解。不过都要上HoldAll了还不愿意用括号,坚持后缀纯函数,代码风格方面不太行。
2021年04月03日 03点04分
@asdasd1dsadsa 这个情况用Unevaluated的话,还凑合……
2021年04月03日 03点04分
1