Вы создаете новую функцию, 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)
.
До сих пор для теории, но на практике это можно сделать только тогда, когда вы можете создавать замыкания, то есть функции с некоторыми данными из их (лексической) среды для закрытия. (Или, если у вас есть какой-нибудь способ, чтобы эмулировать, что, как дополнительный void * user_data
параметр, используемые в некоторых библиотеках C)
Кроме того, так как вы помечены это с численной-интеграцией, то необходимо учитывать, что размер шага, используемый 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)
язык программирования Что мы говорим здесь? Это могло бы помочь в ответе. –
Нет вообще, это чисто теоретический вопрос - этот гипотетический подпрограмма (f) принимает функцию в качестве аргумента и точно ее интегрирует по фиксированному интервалу - [0,1]. Проблема состоит в том, чтобы «обмануть» эту рутину в вычислении интеграла от f по произвольному интервалу [a, b], подав ему другую функцию в качестве аргумента (которая имеет тот же интеграл по [0,1], что и f [ а, Ь]). –