使用函数积分(f)计算f超过[0,1]的积分,以计算任何间隔f的积分

时间:2016-01-27 22:33:04

标签: math numerical-methods numerical-integration numerical-analysis

如何使用(假设的)例程积分(f)计算函数f超过[0,1]的积分来计算f在任何区间[a,b]上的积分?

如果我想更改积分间隔,​​我会使用以下替换:

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

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

这意味着我现在可以在[0,1]上计算积分f(y)*(ba)dy,以获得从[a,b]上积分f(x)dx得到的相同结果funtion integral()接受一个参数 - 一个函数 - 我很难弄清楚如何使用我发现的替代函数来获得该函数。

1 个答案:

答案 0 :(得分:1)

您创建了一个新函数g,它是原始函数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

然后将此功能传递给integral。结果需要(b - a)缩放(因为步骤也已缩放)。

到目前为止理论上,但实际上你只能在创建闭包时执行此操作,闭包是从其(词法)环境中关闭的某些数据的函数。 (或者,如果您有某种方法可以模拟它,就像在某些C库中使用的其他void * user_data参数一样)

此外,由于您使用数字集成对此进行了标记,因此您需要考虑integral使用的步长适用于许多函数,但缩放步长可能是大到整合以产生正确的结果。

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,其中"跟踪"输出显示评估测试函数的点。

这里是一个C版本,通过分配全局静态变量来模拟所提到的闭包:

#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