Используйте функциональный интеграл( f ), который вычисляет интеграл от f по [0,1], чтобы вычислить интеграл от f по любому интервалу

Как использовать (гипотетический) рутинный интеграл ( f ), который вычисляет интеграл функции f по [0,1], чтобы вычислить интеграл f по любому интервалу [a, b]?

Если бы я хотел изменить интервал интегрирования, я бы использовал следующую замену:

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

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

Это означает, что теперь я могу вычислить интеграл f(y)*(ba)dy по [0,1], чтобы получить тот же результат, что и при интегрировании f(x)dx по [a,b], однако интеграл функции () принимает один аргумент — функцию — и мне трудно понять, как использовать подстановку, которую я нашел, для получения этой функции.


person A.F.K.    schedule 27.01.2016    source источник
comment
О каком языке программирования здесь идет речь? Это может помочь сориентироваться в ответе.   -  person Jorge Torres    schedule 28.01.2016
comment
Вовсе нет, это чисто теоретический вопрос - этот гипотетический стандартный интеграл ( f ) принимает функцию в качестве аргумента и точно интегрирует ее по фиксированному интервалу - [0,1]. Проблема состоит в том, чтобы заставить эту процедуру вычислить интеграл от f по произвольному интервалу [a,b], передав ему в качестве аргумента другую функцию (которая имеет тот же интеграл по [0,1], что и f по [a, b]. б]).   -  person A.F.K.    schedule 28.01.2016


Ответы (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).

Пока что для теории, но на практике вы можете сделать это только тогда, когда вы можете создавать замыкания, то есть функции с некоторыми данными из их (лексического) окружения для закрытия. (Или если у вас есть способ эмулировать это, например, дополнительный параметр 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))))))

Вы можете увидеть его в действии, где вывод "Трассировка" показывает, в каких точках оценивается тестовая функция.


А вот версия 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;
}

(в действии)

person Daniel Jour    schedule 27.01.2016
comment
Спасибо за этот подробный ответ. Этот вопрос носит чисто теоретический характер: процедура Integer(f) должна быть черным ящиком, о котором мы знаем только то, что он может точно вычислить интеграл от f по [0,1], и, учитывая это знание, задача состоит в том, чтобы манипулировать процедурой в вычисление интегралов по произвольным интервалам. - person A.F.K.; 28.01.2016
comment
Вычисление (b-a) * интеграла (g), где g = f(a + x(b-a)) должно помочь, верно? - person A.F.K.; 28.01.2016