MathGroup Archive 2011

[Date Index] [Thread Index] [Author Index]

Search the Archive

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



  • Prev by Date: Re: precision of y-axis values in plot
  • Next by Date: Re: precision of y-axis values in plot
  • Previous by thread: Re: NMinimize problem: fct minimized uses FindRoot
  • Next by thread: Re: NMinimize problem: fct minimized uses FindRoot