Maybe let me state my situation in pseudo-C++-code first:
std:vector<double> sample(someFunctor f, double lower, double upper) {
double t = (lower + upper)/2;
double newval = f(t);
if (f(upper) - newval > epsilon)
subsample1 = sample(f, t, upper);
if (newval - f(lower) > epsilon)
subsample2 = sample(f, lower, t);
return concat(subsample2, newval, subsample1);
}
where concat just, well, concats the returned vectors. Basically, I am sampling a function in a way such that between two saved function values there is only a small difference.
I am not happy with the way stated above as there seems to be quite a bit of memory allocation (allocate two subvectors, then concat those and another element) in every recursive step. That piece of code will have to run in a part of my algorithm that is critical with respect to performance. Once upper - lower
is fairly small, evaluating f
will not take a great amount of time.
So my questions:
Do you see a clever way to use the same data structure in all recursive calls and just fill the current parts of that vector? (Keeping in mind that the number of function evaluations needed is not known upfront). Thoughts on this:
- Using a list instead of a vector. But I feel the memory overhaul is not adequate for just storing doubles.
- Keep holes in the vector and maintain another vector saying which entries are filled. A the end of a recursive call shift the entries so that there are no holes between the
subsample
s andnewval
. But now I switch copying by shifting with additional work for the second vector - probably bad idea.
Do you see a way to get rid of the recursion totally? However, for correctness it is important that I use the divide-and-conquer pattern stated above. The function
f
makes heavy use of the upper and lower bounds and gains quite a big deal of performance by this.
Thank's for your thoughts.
As per Space_C0wb0y's request let me try to rephrase my problem. Maybe the first explanation was not very clear.
I have some function (in a mathematical sense) that I want to sample (e.g. to evaluate at certain points) in a given interval.
Suppose that interval is [0,100]. I know the functions values at 0 and at 100. Maybe that is f(0)=0
and f(100) = 40
.
Now I evaluate the function at the intervals midpoint, which is 50. Say, my function returns f(50)=10
.
As f(0)-f(50) <= 10
, I do not need further samples in the interval [0,50]. However, I need further computations for the interval [50,100]. Thus, in the next (recursive) step I evaluate f(75)
. Now repeat the above logic recursively.
At the end I would like to (two) vectors giving me the function values with the corresponding parameters like this:
parameter = vector(0, 50, 56.25, 62.5, 75, 100)
value = vector(0, 10, 17.21, 25 34, 40)
I am looking for the best (as is most performant) approach to build these vectors recursively.
Hope this clarifies things.