0

How to use a (hypothetical) routine integral( f ) which computes the integral of function f over [0,1] to compute the integral of f over any interval [a,b]?

If I wanted to change the interval of integration I would use the following substitution:

y = (x-a)/(b-a)

dy = (1/(b-a))dx

Which means that I can now compute the integral f(y)*(b-a)dy over [0,1] to get the same result I would get from integrating f(x)dx over [a,b], however the funtion integral() takes one argument - a function - and I'm having a hard time figuring out how to use the substitution I've found to derive that function.

A.F.K.
  • 69
  • 7
  • 1
    What programming language are we talking about here? It could help to guide the answer. – Jorge Torres Jan 27 '16 at 22:36
  • None at all, it is purely a theoretical question - this hypothetical routine integral( f ) takes a function as an argument and integrates it accurately over a fixed interval - [0,1]. The problem is to "trick" this rountine into computing an integral of f over an arbitrary interval [a,b] by feeding it a different function as an argument (which has the same integral over [0,1] as f has over [a,b]). – A.F.K. Jan 27 '16 at 22:38

1 Answers1

1

You create a new function, g, which is an appropriately scaled version of the original function f.

g(x) = f(a + x * (b - a))
// Now we have ...
// g(0) = f(a)
// g(1) = f(b)
// ... and the function between is linearly scaled

Then you pass this function to integral. The result needs to be scaled (since the step has also been scaled) by (b - a).

So far for the theory, but in practice you can only do this when you can create closures, that is functions with some data from their (lexical) environment to close over. (Or if you have some way to emulate that, like an additional void * user_data parameter as used in some C libraries)

Also, since you tagged this with numerical-integration, you need to consider that the step size used by integral could be appropriate for many functions, but the scaled step size could be to large for integration to yield correct results.


Small example in Common Lisp:

;; from http://rosettacode.org/wiki/Numerical_integration#Common_Lisp
(defun left-rectangle (f a b n &aux (d (/ (- b a) n)))
  (* d (loop for x from a below b by d summing (funcall f x))))

(defun integral (f)
  (left-rectangle f 0 1 10))


(defun integral-range (f a b)
  (* (- b a) (integral #'(lambda (x) (funcall f (float (+ a (* x (- b a)))))))))

(defun test-fn (x) (* x 2))
(trace test-fn)

(let ((i (integral-range #'test-fn 3 9)))
  (format t "Result of numerical integration: ~a~%" i)
  (format t "Error of numerical integration: ~a~%" (abs (- i (- (* 9 9) (* 3 3))))))

You can see it in action, where the "Trace" output shows at which points the test function is evaluated.


And here a C version, emulating the mentioned closure by assigning global static variables:

#include <stdio.h>
#include <math.h>

// from http://rosettacode.org/wiki/Numerical_integration#C
double int_leftrect(double from, double to, double n, double (*func)())
{
   double h = (to-from)/n;
   double sum = 0.0, x;
   for(x=from; x <= (to-h); x += h)
      sum += func(x);
   return h*sum;
}

double integral(double (*func)()) {
    return int_leftrect(0, 1, 10, func);
}


static double from;
static double to;
static double (*fn)();
double scaled(double x) {
    return fn(from + x * (to - from));
}

double integral_range(double (*func)(), double a, double b) {
    from = a;
    to = b;
    fn = func;
    return integral(scaled) * (b - a);
}

double test_fn(double x) {
    double result = 2 * x;
    printf("TRACE: test_fn(%f) => %f\n", x, result);
    return result;
}

int main(void) {
    double result = integral_range(test_fn, 3, 9);
    double expected = (9 * 9) - (3 * 3);
    printf("result of numerical integration: %f\n", result);
    printf("error of numerical integration: %f\n", fabs(result - expected));
    return 0;
}

(In action)

Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
  • Thanks for this indepth answer. This question is purely theoretical - the procedure integral( f ) is meant to be a black box about which we only know that it can compute the integral of f over [0,1] accurately and given this knowledge the task is to manipulate the procedure into computing integrals over arbitrary intervals. – A.F.K. Jan 28 '16 at 00:11
  • Computing (b-a) * integral( g ), where g = f(a + x(b-a)) should do the trick, right? – A.F.K. Jan 28 '16 at 00:17