如何使用(假设的)例程积分(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()接受一个参数 - 一个函数 - 我很难弄清楚如何使用我发现的替代函数来获得该函数。
答案 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;
}