Переписать код с Лиспа на императивный язык: Вычисление двойного интеграла - Lisp
Формулировка задачи:
Есть код (если я правильно узнал язык) на Лиспе, описывающий вычисление двойного интеграла методом ячеек. К сожалению, я совершенно не знаю Лиспа, поэтому прошу помочь перевести это на "нормальный" императивный язык (желательно С/С++).
Входные данные(function.txt):
;; функция вычисления интеграла (defun double_integral (ax bx ay by g f) ;; ширина ячейки (setq h1 (/ ( - bx ax) g)) ;; высота ячейки (setq h2 (/ ( - by ay) g)) ;; площадь ячейки (setq S (* h1 h2)) ;; переменная для вычисления интеграла (setq I 0) ;; интегральная сумма (setq I (sum_delt ( - bx (/ h1 2)) (+ ay (/ h2 2)) ax bx ay by h1 h2 I f)) ) ;; вычисление суммы площадей ячеек (defun sum_delt (x y ax bx ay by h1 h2 I f) (cond ( (>= y by) I) (T (sum_delt ( - bx (/ h1 2)) (+ y h2) ax bx ay by h1 h2 (delta_x x y ax h1 h2 I f) f)) ) ) ;; вычисление площади ячейки в точке x y (defun delta_x (x y ax h1 h2 I f) (cond ( (<= x ax) I) (T (delta_x ( - x h1) y ax h1 h2 (+ I (* h1 h2 (funcall f x y))) f)) ) ) ;; подгружаем функцию и пределы интегрирования (load "D: \\function. txt") ;; вычисляем интеграл (setq I (double_integral a_x b_x a_y b_y count_dot (function f))) ; открываем файл для записи (setq output-stream (open " d: \\integral. txt": direction: output)) ;; записываем результат интегрирования в файл (format output-stream "Integral = ~a" I) ; закрываем файл (close output-stream) ;; end Файл function. txt ;; интегрируемая функция (defun f (x y) (+ ( - 1 x) (* y y)) ) ;; начальный предел по x (setq a_x 0.5) ;; конечный предел по x (setq b_x 1) ;; начальный предел по y (setq a_y - 3) ;; конечный предел по y (setq b_y 2) ;; количество ячеек (setq count_dot 100)
;;интегрируемая функция
(defun f(x y)
(+(-1 x) (* y y) )
)
;;начальный предел по х
(setq a_x 0.5)
;;конечный пределе по х
(setq b_x 1)
;;начальный предел по у
(setq a_y -3)
;;конечный предел по у
(setq b_y 2)
;;количество ячеек
(setq count_dot 100)f - интегрируемая функция; ax - начальный предел интегрирования по x; bx - конечный предел интегрирования по x; ay - начальный предел интегрирования по y; by - конечный пределе интегрирования по y; g - количество ячеек; h1 - ширина ячейки; h2 - высота ячейки; S - площадь ячейки; I - интеграл от функции f; x, y - координаты центра ячейки.
Решение задачи: «Переписать код с Лиспа на императивный язык: Вычисление двойного интеграла»
textual
Листинг программы
#include <stdio.h>
double delta_x (double x, double y, double ax, double h1, double h2, double I, double (*f) (double x, double y)) {
if (x <= ax) {
return I;
} else {
return delta_x(x - h1, y, ax, h1, h2, I + h1 * h2 * (*f)(x, y), f);
}
}
double sum_delt (double x, double y, double ax, double bx, double ay, double by, double h1, double h2, double I, double (*f) (double x, double y)) {
if (y >= by) {
return I;
} else {
return sum_delt(bx - h1/2, y + h2, ax, bx, ay, by, h1, h2, delta_x(x, y, ax, h1, h2, I, f), f);
}
}
double double_integral (double ax, double bx, double ay, double by, int g, double (*f) (double x, double y)) {
double h1 = (bx - ax)/g;
double h2 = (by - ay)/g;
double S = h1 * h2;
double I = 0;
I = sum_delt(bx - h1/2, ay + h2/2, ax, bx, ay, by, h1, h2, I, f);
return I;
}
double f(double x, double y) {
return ((1 - x) + y * y);
}
int main(int argc, char* argv[]) {
double a_x = 0.5;
double b_x = 1;
double a_y = -3;
double b_y = 2;
int count_dot = 100;
double I = double_integral(a_x, b_x, a_y, b_y, count_dot, &f);
printf("Integral = %f\n", I);
}
Объяснение кода листинга программы
Код представляет собой реализацию вычисления двойного интеграла методом деления отрезка на равные части (или сетку) и последующего суммирования значений функции в каждой точке этого отрезка. Вот список действий, которые выполняются в коде:
- delta_x: Эта функция реализует рекурсивный алгоритм для вычисления значения двойного интеграла. Если текущее значение x меньше или равно ax, функция возвращает значение I. В противном случае, функция вызывает саму себя, передавая в качестве аргументов новые значения x, y, ax, h1, h2, I и функцию f.
- sum_delt: Эта функция также реализует рекурсивный алгоритм для вычисления значения двойного интеграла. Если значение y больше или равно by, функция возвращает значение I. В противном случае, функция вызывает саму себя, передавая в качестве аргументов новые значения bx, y, ax, bx, ay, by, h1, h2, значение, полученное из вызова функции delta_x, и функцию f.
- double_integral: Эта функция вычисляет значение двойного интеграла. Сначала она вычисляет значения h1 и h2, которые представляют собой шаги по осям x и y соответственно. Затем она вычисляет значение S, которое представляет собой площадь прямоугольника, образованного шагами h1 и h2. Затем она инициализирует значение I как 0 и вызывает функцию sum_delt, передавая в качестве аргументов последние значения bx, y, ax, bx, ay, by, h1, h2 и I. Наконец, она возвращает значение I.
- f: Эта функция представляет собой функцию, которую нужно интегрировать. В данном случае она возвращает значение ((1-x) + y*y).
- main: Эта функция является точкой входа в программу. Она инициализирует значения переменных a_x, b_x, a_y, b_y и count_dot. Затем она вызывает функцию double_integral, передавая в качестве аргументов эти значения и функцию f. Наконец, она выводит значение I на экран.