# Use compiled function in FindMinimum/NMinimize (recurring issue...)?

Posted 2 months ago
336 Views
|
6 Replies
|
0 Total Likes
|
 This is an issue that has been discussed before in various forums. Unfortunately I cannot get the proposed fixes to work.The example below is a highly simplified version of the problem I need to solve. In a nutshell, the code runs with a noncompiled objective function (ff below) but fails with a compiled objective function (cff below) as FindMinimum (same for NMinimize) try to evaluate it symbolically. I tried embedding the compiled objective function in another function (as proposed on other websites for NIntegrate) in various manners, to no avail. Perhaps something changed going to Mathematica 12?Code and output are below: ClearAll[xmax, n, k, nk, ktable, xytable, ff, cff]; xmax = 2.; n = 10; nk = 15; ktable = Table[phi = Pi (i - 1)/nk ; 2 Pi Cos[phi] // N, {i, 1, nk}] xtable[] := RandomReal[{-xmax, xmax}, {n}]; ff[xtable_, ktable_, nk_, n_] := Module[{is, ik}, Min[Abs[ Table[Sum[Exp[I ktable[[ik]] xtable[[is]]] , {is, 1, n}], {ik, 1, nk}]]] ]; cff = Compile[{{xtable, _Real, 1}, {ktable, _Real, 1}, {nk, _Integer}, {n, _Integer}}, Module[{is, ik}, Min[Abs[ Table[Sum[Exp[I ktable[[ik]] xtable[[is]]] , {is, 1, n}], {ik, 1, nk}]]] ], "RuntimeOptions" -> {"EvaluateSymbolically" -> False}, CompilationTarget -> "C"]; res1 = FindMinimum[{ff[vars, ktable, nk, n]}, varsp, Compiled -> True] res2 = FindMinimum[{cff[vars, ktable, nk, n]}, varsp, Compiled -> True] Produces: Out= {6.28319, 6.14588, 5.73998, 5.0832, 4.20427, 3.14159, \ 1.94161, 0.656772, -0.656772, -1.94161, -3.14159, -4.20427, -5.0832, \ -5.73998, -6.14588} During evaluation of In:= FindMinimum::lstol: The line search decreased the step size to within the tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the function. You may need more than MachinePrecision digits of working precision to meet these tolerances. Out= {0.0000312628, {x -> -1.20209, x -> 1.56411, x -> -2.38736, x -> 2.69716, x -> 1.69609, x -> 1.62822, x -> -1.07591, x -> 1.21886, x -> -2.32379, x -> 1.34694}} During evaluation of In:= CompiledFunction::cfta: Argument {x,x,x,x,x,x,x,x,x,x} at position 1 should be a rank 1 tensor of machine-size real numbers. During evaluation of In:= CompiledFunction::cfta: Argument {x,x,x,x,x,x,x,x,x,x} at position 1 should be a rank 1 tensor of machine-size real numbers. During evaluation of In:= CompiledFunction::cfta: Argument {x[1.],x[2.],x[3.],x[4.],x[5.],x[6.],x[7.],x[8.],x[9.],x[10.]} at position 1 should be a rank 1 tensor of machine-size real numbers. During evaluation of In:= General::stop: Further output of CompiledFunction::cfta will be suppressed during this calculation. During evaluation of In:= FindMinimum::lstol: The line search decreased the step size to within the tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the function. You may need more than MachinePrecision digits of working precision to meet these tolerances. Out= {0.0000312628, {x -> -1.20209, x -> 1.56411, x -> -2.38736, x -> 2.69716, x -> 1.69609, x -> 1.62822, x -> -1.07591, x -> 1.21886, x -> -2.32379, x -> 1.34694}} Answer
6 Replies
Sort By:
Posted 2 months ago
 the error messages are saying that your compiled function is not working correctly. Answer
Posted 2 months ago
 The compiled function works when not called from FindMinimum In:= cff[xtable[], ktable, nk, n] Out= 1.30685 Similar issues were discussed in: - for NIntegrate: https://mathematica.stackexchange.com/questions/17993/using-a-compiled-function-inside-nintegrate-gives-compiledfunctioncfsa-messaUnfortunately I cannot seem to duplicate these successes. Answer
Posted 2 months ago
 It may not work for all the different values passed to it by FindMinimum Answer
Posted 2 months ago
 Since xtable[] is defined with delayed evaluation, it will give a different result every time it is called. Is that your intention? Answer
Posted 2 months ago
 yes, that was the intention, as it allowed me to test cff in a loop for many different arguments. The issue remains that FindMinimum and NMinimize appear to evaluate the objective function symbolically as implied by the error messageDuring evaluation of In:= CompiledFunction::cfta: Argument {x,x,x,x,x,x,x,x,x,x} at position 1 should be a rank 1 tensor of machine-size real numbers. Answer
Posted 2 months ago
 why isn't xtable the first argument of ff and cff in FindMinimum: In:= xmax = 2.; In:= n = 10; nk = 15; In:= ktable = Table[Pi (i - 1)/nk; 2 Pi Cos[phi] // N, {i, 1, nk}]; In:= xtable := RandomReal[{-xmax, xmax}, {n}]; In:= ff[xtable_, ktable_, nk_, n_] := Module[{is, ik}, Min[Abs[Table[ Sum[Exp[I ktable[[ik]] xtable[[is]]], {is, 1, n}], {ik, 1, nk}]]]]; In:= cff = Compile[{{xtable, _Real, 1}, {ktable, _Real, 1}, {nk, _Integer}, {n, _Integer}}, Module[{is, ik}, Min[Abs[Table[ Sum[Exp[I ktable[[ik]] xtable[[is]]], {is, 1, n}], {ik, 1, nk}]]]], "RuntimeOptions" -> {"EvaluateSymbolically" -> False}, CompilationTarget -> "C"]; In:= FindMinimum[{ff[xtable, ktable, nk, n]}, varsp, Compiled -> True] During evaluation of In:= FindMinimum::fmgz: Encountered a gradient that is effectively zero. The result returned may not be a minimum; it may be a maximum or a saddle point. Out= {1.74504, {varsp -> 1.}} In:= FindMinimum[{cff[xtable, ktable, nk, n]}, varsp, Compiled -> True] During evaluation of In:= FindMinimum::fmgz: Encountered a gradient that is effectively zero. The result returned may not be a minimum; it may be a maximum or a saddle point. Out= {1.15655, {varsp -> 1.}} Answer