Group Abstract Group Abstract

Message Boards Message Boards

0
|
9.7K Views
|
10 Replies
|
4 Total Likes
View groups...
Share
Share this post:

[?] Postprocess a ContourPlot to find minimum and maximum values?

Posted 8 years ago
POSTED BY: James D Hanson
10 Replies
Posted 8 years ago

You can use Reap and Sow to collect function values sampled by ContourPlot using it's option EvaluationMonitor. Then you can either select the minimum value or interpolate the points and apply NMinimize.

POSTED BY: Alexey Popkov
POSTED BY: Gianluca Gorni
POSTED BY: Neil Singer
Posted 8 years ago

This was the clue I needed. Thank you.

In my actual problem, I had a legended ContourPlot, and the maximum and minimum values found by Mathematica are used for the ColorFunction scaling.

Here is an example. The command below generates a simple ContourPlot with minimum 0.11111 and maximum 0.23456, with a Legend.

cp = ContourPlot[
  a + (b - a) x /. {a -> .11111, b -> .23456}, {x, 0, 1}, {y, 0, 1}, 
  PlotLegends -> Automatic]

Looking at a Shallow version of the FullForm shows that the [[2,1]] Part of cp is the BarLegend.

Shallow[FullForm[cp], 5]

The first argument to BarLegend is a list, the second element of which is a list of the minimum and maximum values for use in the ColorFunction scaling.

cp[[2, 1, 1, 2]]

and the result is

{0.11111, 0.23456}
POSTED BY: James D Hanson
POSTED BY: Neil Singer
Posted 8 years ago

Thank you for your suggestion to first generate the values in a table, and then generate the plot from that. That approach is not quite what I was looking for, because then I lose the benefits of the adaptive evaluation algorithm the Mathematica uses when generating the contour plot.

Your comment from two days is most intriguing. I have been busy, but when I first got your comment, I looked at the link you provided, http://community.wolfram.com/groups/-/m/t/1128342 and I recall that there were two functions applied to the ContourPlot function, I think the first one was Normalize. It looked like the direction I wanted to go in - post-processing the ContourPlot.

Today, when I navigated to that link, I got the message

We're sorry, the thread you were looking for is no longer available. It could have been deleted by the original author or removed by our moderation team.

Seems strange to me.

Do you have any further information about the post-processing approach?

POSTED BY: James D Hanson

James,

You should generate your data first, and then generate your contour plot.

cpdata = Table[
  x y Sin[30 x] Sin[20 y], {y, 0, 1, .01}, {x, 0, 1, .01}]
ListContourPlot[cpdata, DataRange -> {{0, 1}, {0, 1}}]

you get the same contour plot. Note that Contourplot does not find maxima -- it just plots the digitized function. You can get approximate values (the same ones you would get by processing the contourplot data) by processing the cpdata.

You could use Max and Position to find the max value of the digitized data. You can also use Interpolation to create a fast 2D function for Maximize and other data exploration functions which would give you your values. You could even use the interpolation maxima as a starting point for a FindMaximum on your complex function (with really good bounds) to get more precision, if needed.

For example:

In[23]:= Max[cpdata]
Out[23]= 0.853278
In[24]:= Position[cpdata,Max[cpdata]]
Out[24]= {{88,101}}
In[25]:= N[x y Sin[30 x] Sin[20 y]/. x->100/100/.y->87/100]
Out[25]= 0.853278

Or regenerate the data in Interpolation format: (Note -- I made x go a bit larger than 1 because the max we found was at 1)

cpdata2 = Flatten[Table[{{x,y},x y Sin[30 x] Sin[20 y]},{y,0,1,.01},{x,0,1.1,.01}],1];
cdi = Interpolation[cpdata2]

In[30]:= cdi[1, .87]

Out[30]= 0.853278

In[31]:= FindMaximum[cdi[x,y],{{x,1,.99,1.01},{y,.87,.86,.88}}]
Out[31]= {0.861212,{x->0.995971,y->0.866834}}

Hope this helps

Regards,

Neil

POSTED BY: Neil Singer

yes, global optimization is hard

POSTED BY: Frank Kampas
In[1]:= Minimize[{x y Sin[30 x] Sin[20 y], 0 <= x <= 1, 
  0 <= y <= 1}, {x, y}]

Out[1]= {Root[{Sin[30 #1] + 30 Cos[30 #1] #1 &, 
    0.99595288353691310152}] Sin[20] Sin[
   30 Root[{Sin[30 #1] + 30 Cos[30 #1] #1 &, 
      0.99595288353691310152}]], {x -> 
   Root[{Sin[30 #1] + 30 Cos[30 #1] #1 &, 0.99595288353691310152}], 
  y -> 1}}

In[2]:= N[%]

Out[2]= {-0.908742, {x -> 0.995953, y -> 1.}}

Use Maximize to find the maximum value

POSTED BY: Frank Kampas
Posted 8 years ago

The problem with Maximize and NMaximize is that they 1) revaluate the function (that has already been evaluated in ContourPlot), and 2) they are not terribly robust when there are multiple maxima.

Note that the function x y Sin[30 x] Sin[20 y]` that I used above was a proxy for the function I really want to use, which is significantly more complicated, and takes significantly more time to evaluate.

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