3
$\begingroup$

If I use FindMinimum on a function of one variable, AccuracyGoal and PrecisionGoal will find a solution to the required accuracy/precision, which will be quicker as it requires less evaluations:

test1[a_?NumericQ] := Module[{},
  Abs[x[1]]/.NDSolve[{x''[t] == a x[t], x[0] == 1, x'[0] == 0},x, {t, 0, 1}][[1]] ]

Block[{c=0}, {FindMinimum[test1[a], {a,1}, AccuracyGoal -> 1, 
  PrecisionGoal -> 1, Method -> "PrincipalAxis", EvaluationMonitor :> c++], c}]

{{0.000711985, {a -> -2.46516}}, 17}

Block[{c=0}, {FindMinimum[test1[a], {a,1}, Method -> "PrincipalAxis",  EvaluationMonitor :> c++], c}]

{{7.55525*10^-15, {a -> -2.4674}}, 35}

However, when I have a function of two variables, it seems to ignore the goals:

test2[a_?NumericQ, b_?NumericQ] := Module[{},
  Abs[x[1]] /.NDSolve[{x'[t] == a + b x[t], x[0] == 1}, x, {t, 0, 1}][[1]]  ]

Block[{c = 0}, {FindMinimum[test2[a, b], {a, 1}, {b, 1}, 
  AccuracyGoal -> 1, PrecisionGoal -> 1, EvaluationMonitor :> c++],c}]

{{1.72234*10^-9, {a -> -0.611427, b -> -0.914679}}, 232}

Block[{c = 0}, {FindMinimum[test2[a, b], {a, 1}, {b, 1}, 
  EvaluationMonitor :> c++], c}]

{{1.72234*10^-9, {a -> -0.611427, b -> -0.914679}}, 232}

As my function takes about 5 seconds to evaluate and I only care about getting the values to ~2 decimal places, this makes a big difference to how long it takes for the FindMinimum to terminate. Is there a way to get FindMinimum to respect my goals? Or a workaround to get it to stop when it keeps evaluating around the same point to get closer to the root.

I'm using v11.0.0, but it does the same on v9.

$\endgroup$
1
$\begingroup$

As mentioned in

Is manual adjustment of AccuracyGoal and PrecisionGoal useless?

PrecisionGoal and AccuracyGoal are subtle in my opinion. According to my personal experience, adjusting WorkingPrecision is usually more effective when dealing with precision/accuracy issue, and your case seems not to be an exception:

Block[{c = 0}, {FindMinimum[test2[a, b], {a, 1}, {b, 1}, EvaluationMonitor :> c++,
     WorkingPrecision -> 4], c}] // AbsoluteTiming
(* {0.092071, {{0.001083, {a -> -0.6112, b -> -0.9201}}, 52}} *)

BTW, for your specific example, using ParametricNDSolveValue instead of the _?NumericQ trick will speed up the calculation further:

test3 = 
  ParametricNDSolveValue[{x'[t] == a + b x[t], x[0] == 1}, Abs@x[1], {t, 0, 1}, {a, b}];

Block[{c = 0}, {FindMinimum[test3[a, b], {a, 1}, {b, 1}, EvaluationMonitor :> c++,
     WorkingPrecision -> 4], c}] // AbsoluteTiming
(* {0.041535, {{0.001083, {a -> -0.6112, b -> -0.9201}}, 52}} *)
$\endgroup$
  • $\begingroup$ Yes, the specific example is as usual just a toy, my actual system is much more complicated, with a very large coupled set of ODEs. $\endgroup$ – KraZug Mar 4 '17 at 5:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.