Message Boards Message Boards

0
|
5817 Views
|
8 Replies
|
7 Total Likes
View groups...
Share
Share this post:

Use NMinimize calling an own defined function?

Posted 6 years ago

I want to call an own defined function through NMinimize. For the sake of simplicity, let us define the problem as follow:

radpatt[x1_] := (Print[x1]; x1 )

NMinimize[{radpatt[xx], 0.1 <= xx <= 1.1}, {xx}]

If you run the above-listed instructions, you will notice that x1 is not number as soon as the function radpatt is called by NMinimize, but it is equal to xx. This causes me an issue because in my original problem x1 needs to be a number just at the beginning of my own function. Any ideas?

Many many thanks in advance.

8 Replies
Posted 3 months ago

The name of the global context is "Global`". Context names always end in a backtick. The * is a "wildcard" that matches any characters in a symbol name. It is similar to the Unix shell wildcard * — and wildcards on other systems, I'm sure, but I learned computers on a multi-user Unix system before PCs were available. It is explained in the details section near the top of the documentation for Remove. Thus "Global`*" matches all symbol names in the global context. And "Global`q*" would match only symbol names that begin with q.

I use Quit[], which quits and restarts the kernel, instead of Remove["Global`*"], with an empty kernel init.m. Quit[] is usually slower (a few seconds) than Remove[], I think. How slow seems to change from version to version. Restarting the kernel seems closest to what you get when you run a compiled program (just system definitions, no prior user-defined values). As an interpreted environment with persistent definitions from one shift-enter to another (and a shared kernel for all notebooks), it's never exactly the same, though.

There is also the CleanSlate package, which some people use to do a bit more cleanup than Remove["Global`*"].

So much for dealing with clean runs of programs. As for the complexity of the programming environment, as I said in my first post, I don't have a quick answer.

POSTED BY: Updating Name

Thanks a lot! (But I am sorry to say I cannot understand what "context" really means, and I suppose I shall sometimes crash even after understanding it. Sweat ^^;)

POSTED BY: Unknown Unknown

Hi,

Numerical solvers in Mathematica usually analyze the symbolic form of the objective function. To do this analysis, NMinimize[] evaluates radpatt[xx] (in the OP at the top). This analysis may be used for method selection, singularity handling, and perhaps other adjustments. Mathematica is designed to do this automatically and to allow for users to override its automatic choices. It uses heuristics that are not always perfect. Symbolic processing takes time. So user-overrides sometimes are needed and can speed things up when the user knows what they are doing.

Using _?NumericQ in defining the objective function prevents symbolic analysis, and the automatic choice of method is more likely to be less than optimal. Symbolic analysis mainly done on formulas, as far as I know. So if your objective functions calls a numerical routine, such as NIntegrate[] or FindRoot[], then you do not lose much by using _?NumericQ. And if you need to specify singularities or method, you can do that through options. (One irritating-to-me exception: Plot[f[x], {x, 0, 1}, WorkingPrecision -> 32] evaluates f[x] on a machine-precision number at the beginning, and sometimes this causes problems.)

Below are variations on an example. The method, speed, and quality of the result are altered by using _?NumericQ in obj[]. Also the last variant shows that the superior method may not be used on obj[].

(* Uses Couenne NLP *)
NMinimize[{Cos[x] - Exp[(x - 0.5)  y], x^2 + y^2 < 1}, {x, y}] // AbsoluteTiming
(*  {0.03809, {-1.60047, {x -> -0.657103, y -> -0.753805}}}  *)

(* Ends up using diff. evol. after rejecting Couenne *)
obj // ClearAll; (* I always start function definitions this way (or ClearAll[obj] *)
obj[x_?NumericQ, y_?NumericQ] := Cos[x] - Exp[(x - 0.5)  y];
NMinimize[{obj[x, y], x^2 + y^2 < 1}, {x, y}] // AbsoluteTiming
(*  {0.154981, {-1.60046, {x -> -0.657221, y -> -0.753698}}}  *)

NMinimize[{obj[x, y], x^2 + y^2 < 1}, {x, y}, Method -> "Couenne"]
(*  NMinimize::unproc: Could not process the objective and constraints in a form suitable for Couenne.  *)
(*  NMinimize[{obj[x, y], x^2 + y^2 < 1}, {x, y}, Method -> "Couenne"]  *)

If you want to know how I know what is going, here are some undocumented ways to peak under the hood of NMinimize/NMaximize:

Optimization`Debug`SetPrintLevel[2]; 
Block[{Optimization`NMinimizeDump`$DiagnosticLevel = 2},
 (* Uses Couenne NLP *)
 NMinimize[{Cos[x] - Exp[(x - 0.5)  y], x^2 + y^2 < 1}, {x, y}]
 ]
Optimization`Debug`SetPrintLevel[0];

Optimization`Debug`SetPrintLevel[2];
Block[{Optimization`NMinimizeDump`$DiagnosticLevel = 2},
 (* Ends up using diff. evol. after rejecting Couenne *)
 NMinimize[{obj[x, y], x^2 + y^2 < 1}, {x, y}]
 ]
Optimization`Debug`SetPrintLevel[0];
POSTED BY: Michael Rogers

For protecting an objective which is a function of a list of variables use:

obj[vars_?(AllTrue[#, NumberQ] &)]

as suggested to me by Wolfram support

POSTED BY: Frank Kampas

A user-supplied objective function for NMinimize or FindMinimum needs to be "protected" from premature evaluation when given symbolic input. Therefore, use a definition like this

radpatt[x1_?NumberQ] := (Print[x1]; x1 )
POSTED BY: Robert Nachbar
POSTED BY: Unknown Unknown
Posted 3 months ago

Dear Shinji,

There is an example in the current documentation for NMinimize[] (here) that shows the use f2[a_?NumericQ] := .... Note NumberQ[Sqrt[2]] is False but NumericQ[Sqrt[2]] is True. Therefore NumberQ[] is a more restrictive test; per the docs, "NumberQ[expr] returns False unless expr is manifestly a number (i.e. has head Complex, Integer, Rational, or Real)." The expression Sqrt[2] has head Power (another somewhat frequently encountered problem). NumberQ[] may be slightly faster than NumericQ[], but RepeatedTiming[] shows no discernible difference in my tests.

This example had been part of the "knowledge base" tech notes, but I believe it was incorporated into the documentation some years ago. The knowledge base note is still available here: https://support.wolfram.com/12502.

The issue is also discussed in this StackExchange answer. Other answers in that Q&A discuss things someone thinks are helpful for Mathematica users to know, some of which you may find helpful.

As for "the critical language design policies" in general, I'm not sure I can really help. I think I "grok" them. When I started, I read The Mathematica Book by Stephen Wolfram back around 1990. It is (or was for the early versions) a good, intermediate-level guide, with a good introductory Part 1. I came away with a pretty good understanding of "everything-is-an-expression"; that "evaluation" meant rewriting expressions according to pattern-rule operations, and it was not strictly limited to number and string crunching as in C but was more like Lisp, two languages I knew; and that there was "standard evaluation" and "non-standard evaluation." Coming to grips with standard and non-standard evaluation, the significance of Hold* attributes, Hold[], Unevaluated[], Defer[], and up-/down-/sub-values associated to symbols took a bit longer. And now we have Inactive[]. It's complicated. That means it is easy to become confused. Some of it I gave up on and didn't understand for maybe fifteen years or more. Most work does not require an understanding of all the arcane aspects. Much of The Mathematica Book is available in the documentation, tutorial/VirtualBookOverview. It has necessarily been restructured and updated. "The Evaluation of Expressions" may be found under "Core Language."

I mention several aspects of evaluation, because that is at the heart of the problem in the OP, and an appropriate pattern (_?NumericQ) is needed to control the order of evaluation.

I might also mention that at the time I started learning Mathematica, I knew Postscript, which greatly helped with understanding graphics concepts in early Mathematica; and Macaulay and Maple, which greatly helped with understanding symbolic algebra concepts and symbolic computation in general.

POSTED BY: Updating Name

Dear Updating Name,

Thank you very much for your kind advice, including your valuable experience. I am probably much older than you and have no experience (other than a little Mathematica) with symbolic computation, etc. I have a lot of experience with FORTRAN programming and a little with assembler.

These older programs are written to execute in the order of the code statements, and the code looks spaghetti-complex because of the "go to" statements or jump statements, but the order of the operations is easy to understand, and debugging can be successful if done carefully, even if it takes time.

On the other hand, Mathematica's language is convenient for simple examples, but nasty pitfalls appear when I try to do anything even remotely complex. For example, is there an example of a function that needs to perform a symbolic computation in NMaximize[ ]? If numerical computation is inevitably assumed, shouldn't the argument be a number? I am also still stumped by the difference between a list and a number: when I have multiple answers in a list to a function defined using Module[ ], NMaximize[ ] does not work without a message even when I use Part[ ] to extract one answer as a number.

Ever since I started using Mathematica, I have wondered about the initialization of Mathematica programs at the start of execution. I always put the line

Remove["Global`*"];

at the beginning of each program, which is a spell without understanding what ` and * mean.

In conclusion, Mathematica is very useful for computing simple problems such as those given as samples, but when users try to solve their own customized problems, they often end up in a swamp-like pit requiring unknown spells. Wolfram seems to have no intention at this time of removing such difficulties in its product specifications. I am like a pilot who is confused by the autopilot specifications of an airliner and crashes.

POSTED BY: Unknown Unknown
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract