Re: NMinimize problem: fct minimized uses FindRoot
- To: mathgroup at smc.vnet.net
- Subject: [mg123791] Re: NMinimize problem: fct minimized uses FindRoot
- From: Oliver Ruebenkoenig <ruebenko at wolfram.com>
- Date: Mon, 19 Dec 2011 07:20:04 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- References: <201112180936.EAA01637@smc.vnet.net>
On Sun, 18 Dec 2011, Oleksandr Rasputinov wrote: > On Sat, 17 Dec 2011 07:46:03 -0000, Oliver Ruebenkoenig > <ruebenko at wolfram.com> wrote: > >> >> On Fri, 16 Dec 2011, Oleksandr Rasputinov wrote: >> >>> On Thu, 15 Dec 2011 10:06:01 -0000, Oliver Ruebenkoenig >>> <ruebenko at wolfram.com> wrote: >>> >>>> >>>> Just for comepletness sake: >>>> >>>> this does work >>>> >>>> cf = Compile[{{n, _Integer}}, >>>> Module[{res = 0}, Do[res += i; If[res > 10, Throw[0, cfe]], {i, n}]; >>>> res]] >>>> >>>> Catch[cf[111], cfe] >>>> >>>> >>>> Related: >>>> http://stackoverflow.com/questions/8184548/do-return-behave-differently-in-compile-why/8194565#8194565 >>>> >>>> Oliver >>>> >>> >>> Well, sort of. >>> >>> cf // InputForm >>> >>> reveals the MainEvaluate call (opcode 46): >> >> That does not matter - this is evaluated only once; and you want to go >> back to the evaluator anyways. > > No, I really don't. :) The reason I suggested that a compiled form of the Hm, I think we have a different opinion here: If the Catch is not withing the compile, then I think you want to return to the interpreter, if the catch is within the compile then you do not. > two-argument Return, Continue, Break etc. might be useful is that these > could be used for more complex (Fortran 90-like, say, versus Fortran > 77-like) structured flow control in procedural code. (While Throw is > usually a better choice than Return, I still tend to prefer Break and > Continue in a procedural context over co-opting Throw for these purposes > as well.) But once you Throw using a MainEvaluate call, there is no way to > get back into compiled code except by starting again from the beginning, > which is rather contrary to the purpose of flow control in general. As a I think that depends on what you want to do. > result, Label/Goto is left as the only possible solution, anachronistic as > it may be. > >>> >>> Also: >>> >>> cf2 = Compile[{{n, _Integer}}, >>> Catch[ >>> Module[{res = 0}, >>> Do[res += i; If[res > 10, Throw[0, cfe]], {i, n}]; >>> res >>> ], cfe >>> ] >>> ] >>> >>> Catch::argx: Catch called with 2 arguments; 1 argument is expected. >>> >>> cf2 // InputForm >> >> Yes, this seems to me much more of an issue. >> >> I'd cautiously say, that this might be improvable. But I am not sure. I >> think the issue is that the second arg is a expr, which the compiler does >> not know how to deal with. But perhaps if a "string" type were added then >> something like this might work >> >> cf2 = Compile[{{n, _Integer}}, >> Catch[ >> Module[{res = 0}, >> Do[res += i; If[res > 10, Throw[0, "cfe"]], {i, n}]; >> res >> ], "cfe" >> ] >> ] >> >> But this is speculation. > > At the risk of speculating on top of speculation, I don't think this is > correct. The compiler can handle exprs, at least in certain contexts, as The compiler can not handle exprs; the compiler can handle a sub set of exprs. > this example demonstrates (where loop can be an arbitrary expr): > > cf = Compile[{{x, _Integer, 0}}, > Block[{i = x, n = 0}, > Label[loop]; > n += x; > If[--i > 0, Goto[loop]]; > n > ] > ] But in this case the label is transformed into something that the compiler can handle - an integer. Another issue is that say Catch could deal with an integer label, how would that be transformed if CompilationTarget ->C is given. Maybe there is an easy solution, I am not an expert here. > > I think the main reason why the compiler cannot deal with the second > argument to Throw/Catch is that it is not handled as an expr but as a > pattern. If this requirement can be relaxed, it's not inconceivable that That is exactly what I was trying to say, either by a "string" or by an integer - which would be easier since that is something the compiler already understands. > the compiler could in future handle a two-argument Throw/Catch block by > expanding it as a macro. But first, it has to get smarter about handling > this situation: > > Block[{x}, > Block[{}, > x = 1; > Goto[exit]; > ]; > x = 2; > Label[exit]; > x > ] > > This works as expected under normal evaluation, but the presence of the > inner Block confuses the compiler into generating an incorrect > MainEvaluate call that makes it fail when compiled. > Without having thought about this issue too much, it strikes me as tricky. (Well it is not a rainy afternoon project) The interpreter needs to propagate it's state to the compiler. >> >> But this is only a problem if you want to Catch inside compile. So I >> think >> the way to go is to re-write slow parts of code with compile and then the >> control structure in top level. Perhaps some else has another idea? > > I agree, but this may not always be possible while retaining reasonable > performance. Thus, as mentioned above, one might have to use Label/Goto > (compiler bugs notwithstanding) or perhaps link in code written in a > procedural language with more versatile flow control, such as Fortran 90. > You certainly have the option to link in other code, but I think depending on the problem at hand it perhaps could be reformulated such that such a control flow would be avoidable. Really, I in my work have never needed such a control structure. Oliver
- References:
- Re: NMinimize problem: fct minimized uses FindRoot
- From: "Oleksandr Rasputinov" <oleksandr_rasputinov@hmamail.com>
- Re: NMinimize problem: fct minimized uses FindRoot