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