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: [mg123770] Re: NMinimize problem: fct minimized uses FindRoot
  • From: "Oleksandr Rasputinov" <oleksandr_rasputinov at hmamail.com>
  • Date: Sun, 18 Dec 2011 04:36:23 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <201112161047.FAA06783@smc.vnet.net> <jchhbr$ieu$1@smc.vnet.net>

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  
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  
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  
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
   ]
  ]

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  
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.

>
> 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.



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