I am using NMinimize to find parameters that minimise the integral of a function in the least squares sense:
NMinimize[{NIntegrate[f[a,b,x]^2,{x,0,1}], -1 < a < 0, -1 < b < 0},{a,b}]
For some values of the parameters, the function f is not continuous but I know that the minimum value never occurs with parameters for which the function has a discontinuity. I want to do something like the following pseudocode:
For given parameters a and b,
if the function f[a,b,x] is discontinuous on {x,0,1} stop searching for local minima near a and b.
else
proceed with minimization of NIntegrate[f[a,b,x],{x,0,1}] as usual.
I can make this work by using a non-adaptive integration method and reducing the accuracy. But if I leave the accuracy at the default setting NIntegrate takes such a long time to determine that the function is discontinuous that the minimisation becomes computationally infeasible. If I reduce the accuracy then I can get a result in under five minutes but, of course, it's not very accurate.
I've pasted code for a simple example below. In this code I'm estimating the numerical integral before doing NIntegrate by evaluating the function at 100 points. If the estimated integral is not near zero then I use the estimated value instead of proceeding to call NIntegrate. This makes a huge improvement in the speed of the calculation. But I'd still like to know if there's a more elegant solution.
Here are some function definitions that aren't directly related to the question but are necessary to run the example code.
NonzeroLength[X_] := Length[X] - LengthWhile[Reverse[X], # == 0 &]
TransferFunctionNumOrDen[B_, z_] :=
Total[Table[B[[n + 1]]*(z^(-n)), {n, 0, NonzeroLength[B] - 1}]]
TransferFunctionForPlotting[A_, B_, \[Omega]_] :=
Module[{highestDegree},
highestDegree = Max[NonzeroLength[A], NonzeroLength[B]] - 1;
(TransferFunctionNumOrDen[B, E^(-I \[Omega])]*
E^(-I \[Omega]*highestDegree))/(TransferFunctionNumOrDen[A,
E^(-I \[Omega])]*E^(-I \[Omega]*highestDegree))];
secondOrderDelayedAllPass[a_, \[Omega]_] :=
TransferFunctionForPlotting[{1, 0, a}, {0, a, 0, 1}, \[Omega]];
secondOrderAllPass[a_, \[Omega]_] :=
TransferFunctionForPlotting[{1, 0, a}, {a, 0, 1}, \[Omega]];
Here's where we start setting up the numerical minimisation
f[\[Gamma]_, \[Beta]_, lb_, ub_] :=
Module[{phaseDifference, estimate, n = 100},
phaseDifference[\[Omega]_] := Arg[
(Times @@ (secondOrderDelayedAllPass[#, \[Omega]] & /@ \[Gamma])) *
(Times @@ (secondOrderAllPass[#, \[Omega]] & /@ \[Beta]))^(-1)
];
(* estimate the integral with a table *)
estimate = Total[
Table[(\[Pi]/2 - phaseDifference[\[Omega]])^2, {\[Omega], lb,
ub, (ub - lb)/n}]]/(n + 1);
If[
estimate > .3,
estimate,
NIntegrate[(\[Pi]/2 - phaseDifference[\[Omega]])^2, {\[Omega], lb, ub}]
]
]
fmin = 15/22050;
mn = -1 ;
mx = 1;
NMinimize[{f[{a}, {b}, fmin \[Pi], (1 - fmin) \[Pi]], mn < a < mx,
mn < b < mx }, {a, b}, Method -> "DifferentialEvolution"]

NumericQfor the objective function? – J. M.'s missing motivation Aug 24 '15 at 08:12NumericQ, as suggested by GuessWhoItIs. – MarcoB Aug 24 '15 at 15:17\[Gamma] = {a}; \[Beta] = {b};,phaseDifference[\[Omega]]givesArg[((1 + b E^(2 I \[Omega])) (a E^(I \[Omega]) + E^(3 I \[Omega])))/((b + E^(2 I \[Omega])) (1 + a E^(2 I \[Omega])))], which won't be singular sinceaandbare constrained. So the minimisation is delayed by something else. I could try working with a discontinuous function but I suspect it's not what you want. I suggest rewording the question to ask how to speed up the minimization instead of handling discontinuities. – obsolesced Jul 22 '16 at 04:47