Summary: Performance of numerical functions decreases with time
- To: mathgroup <mathgroup at yoda.physics.unc.edu>
- Subject: Summary: Performance of numerical functions decreases with time
- From: Magnus Nordborg <magnus at fisher.stanford.edu>
- Date: Fri, 16 Jul 93 09:40:58 -0700
Thanks to all that responded to this question, including several staff members at WRI.
The problem (see original posting below) is caused by a bug in Mathematica 2.1's
pseudo-compiler (invoked automatically by FindMinimum) that causes symbols to
accumulate over time. Five fixes were suggested:
1.) SetOptions[FindMinimum,Compiled->False]
2.) Use something like:
leftoverCompileNames = Names["Compile`*"];
Scan[Unprotect, leftoverCompileNames];
Scan[Clear, leftoverCompileNames];
Scan[Remove, leftoverCompileNames];
every loop.
3.) Compile the function yourself, then use 1.)
4.) Get 2.2
5.) Use C/MathLink
I tried 1.) and 5.). It might be of interest that 1.) finished in less than 10 hours,
compared to the 20 h I estimated from running 30 iterations with Compiled->True.
Using MathLink (and still looping inside Mathematica, but using a Brent's minimizer
from NetLib) as in 5.) was about 40 times faster again.
Again, thanks to all that responded,
-Magnus
---
Magnus Nordborg
magnus at fisher.stanford.edu (NeXT mail preferred)
Department of Biological Sciences
Stanford University
Stanford, CA 94305-5020
+1 (415) 723-4952 (office)
Begin original message:
Date: Tue, 13 Jul 93 13:57:47 -0700
From: Magnus Nordborg <magnus at fisher.Stanford.EDU>
To: mathgroup <mathgroup at yoda.physics.unc.edu>
Subject: Performance of numerical functions decreases with time
Hi,
I have a "time-critical" question here. I want to find the minimum of a simple
function for many different parameters. I define something like:
MyFunction[d_,s_,z_,a_,b_,g_,k_] :=
Module[{fn,res},
fn = - 2*(1 - d)*M^z*(1 - M^g)^k*s -
(1 - M^g)^k*(1 - (1 - M^a)^b)*(1 - M^z*s);
res = FindMinimum[ fn, {M,0.5}][[2]];
If[ MatchQ[res,{Rule_}],
M /. res,
(* else *)
res = FindMinimum[ fn, {M,0.1}][[2]];
If[ MatchQ[res,{Rule_}],
M /. res,
(* else *)
res = FindMinimum[ fn, {M,0.9}][[2]];
If[ MatchQ[res,{Rule_}],
M /. res,
(* else *)
Null
]
]
]
]
This particular pattern tries several starting points, but everything I say below applies
equally well to the simplest possible pattern. Now, I am trying to use "Table" to find
the minimum for 10^5 different values, say. I did some small number (like 10) and
then extrapolated to find that my job would take on the order of 20 hours (this is using
Sparc 2 and NeXT). 80 hours later the machines are still crunching. So I did a little
test. I timed 35 cases, then redid the same 35 cases, and so on 10 times. To my
chagrin, I find that the performance is decreasing over time!
why = Table[ Timing[ Table[
{0.1,0.1,0.1,1.5,5,1.5,k,
MyFunction [0.1,0.1,0.1,1.5,5,1.5,k]},
{k,1.5,10,0.25}] ], {i,10} ];
Transpose[why][[1]]
{23.8333 Second, 26.2833 Second, 28.85 Second,
31.6667 Second, 34.5167 Second, 37.0833 Second,
39.7 Second, 42.6 Second, 45.5 Second, 48.5833 Second}
It doesn't take the proverbial rocket scientist to see that if time to completion more
than doubles after doing 300 cases, 10^5 will take a bit MORE than 20 h...
What on earth is going on here? What is causing this, and is there a work-around?
We really need these numbers fast, unfortunately. Time for C...?
Grateful for a quick reply,
-Magnus
---
Magnus Nordborg
magnus at fisher.stanford.edu (NeXT mail preferred)
Department of Biological Sciences
Stanford University
Stanford, CA 94305-5020
+1 (415) 723-4952 (office)
P.S. I'm using Mathematica 2.1 on NeXT and Sparc.