|
Государственный комитет Российской Федерации по телекоммуникациям
Сибирский государственный университет
телекоммуникаций и информатики
Курсовая работа
По дисциплине «Вычислительная математика»
Вариант №7.
Работу выполнил
студент 3 курса
группы ЗП-11
Шифр: 7411127П
Мочалов С. С.
Работу проверил
Рягин Б. А.
Работа защищена
«___» __________2013г.
Новосибирск 2013
СОДЕРЖАНИЕ
1. Задание.......................................................................................................... 3
2. Введение........................................................................................................ 4
3. Постановка комплекса задач........................................................................ 6
4. Описание методов вычисления на псевдокоде............................................. 7
5. Проектный раздел......................................................................................... 8
6. Исходный модуль программы..................................................................... 9
7. Результаты тестирования выполнения задания............................................. 13
8. Список литературы........................................................................................ 15
1. ЗАДАНИЕ
Написать программу на языке Си для решения следующей задачи. Все результаты расчетов должны выводится на экран и в файл.
Ток в электрической цепи описывается дифференциальным уравнением (см. стр. 24), которое необходимо решить, найдя y(0.1), y(0.2)... y(1) с помощью метода Рунге-Кутта второго порядка с коррекцией в средней точке. В дифференциальном уравнении k – наименьший положительный корень уравнения x5-x3-3=0, который найти с помощью метода половинного деления, точность e=0.0001.
Вариант дифференциальное уравнения.
2. ВВЕДЕНИЕ
Часто возникает необходимость, как в самой математике, так и ее приложениях в разнообразных областях получать решения математиче-ских задач в числовой форме.
При этом для многих задач известно только о существовании решения, но не существует конечной формулы, представляющей ее решение. Да-же при наличии такой формулы ее использование для получения от-дельных значений решения может оказаться неэффективным.
Во всех этих случаях используются методы приближенного, в пер-вую очередь численного решения.
Основная цель курсовой работы изучение числовых методов на практике.
3. ПОСТАНОВКА КОМПЛЕКСА ЗАДАЧ
Для реализации поставленной задачи необходимо создать процедуры вычислений, отладчик, который будет собирать информацию о вычислениях.
Результаты вычислений выводятся на дисплей, а так же их можно сохранять в текстовый файл.
В программе выбор желаемого действия происходит через меню - вычисления, просмотр, добавление записей будет реализовано через меню.
Ввод команд производим через клавиатуру.
4. ОПИСАНИЕ МЕТОДОВ ВЫЧИСЛЕНИЯ НА ПСЕВДОКОДЕ
4.1 Описание алгоритма вычисления корня уравнения методом половинного деления.
a, b, c - значения функции на отрезках.
h - шаг поиска отрезка, где функция меняет знак.
f(x) - некое уравнение.
e - заданная точность вычисления корня.
поиск отрезка на котором будет производиться вычисления корня:
DO (!(f(a) * f(b) < 0))
a = a - h; b = b + h;
OD;
вычисление корня методом половинного деления:
DO
c = (a + b) / 2;
if ((f(a) * f(c)) < 0) b = c;
else a = c;
if (((b - a) / 2) > e) OD;
OD;
Return c;
4.2 Описание алгоритма вычисления дифференциального уравнения методом Рунге-Кутта второго порядка с коррекцией в средней точке.
n; - кол-во значений.
xi; - значения переменной.
yi; - значения функции.
h - шаг.
F(xi, yi) - дифференциальное уравнение.
k = f(x); - параметр в дифференциальном уравнении.
x0 = 0;
y0 = 0.1;
DO (x0 = 0,..., xi < n - 1)
yi+1 = yi + h * F((xi + h/2), (yi + h/2 * F(xi, yi)));
OD;
5. ПРОЕКТНЫЙ РАЗДЕЛ
До реализации основной программы в заголовке объявляются типы для обратного вызова функций. Они необходимы для передачи ссылок на процедуры вычисления корня степенного уравнения, и вычисления значений дифференциального уравнения описанного в задаче.
typedef double (*callback_exponential_equation)(double);
typedef double (*callback_differential_equation)(double, double);
Затем описываются функции в которых выполняются необходимые вычисления:
double exponential_equation(double);
уравнение по которому узнаем наименьший положительный корень k
для подстановки его в диффиринциальное уравнение
в качестве аргумента используется число с плавающей точкой
double differential_equation(double, double);
дифференциальное уравнение
в качестве аргумента используются числа с плавающей точкой
double method_half_division(callback_exponential_equation);
решение уравнения методом половиннго деления
в качестве аргумента служит ссылка на процедуру уравнения
void calculate_differential_equation();
функция расчета дифференциального уравнения
Класс отладчика позволяет собирать информацию о вычислениях
выводит данные на дисплей или сохраняет их в текстовый файл
Интерфейс класса отладчика:
void Debug::insert(char*);
Записывает сообщение отладки в стек сообщений.
void Debug::print();
Выводит сообщения из стека.
void Debug::write();
Записывает сообщения в файл.
void Debug::clean();
Очищает все сообщения отладчика.
bool Debug::empty();
Проверяет наличие отладочной информации. Возвращает истинну если сообщений нет.
В основной программе main():
Описан бесконечный цикл for(;;) внутри которого идет присваивание переменной выбора пункта меню с клавиатуры. Затем это значение обрабатывается оператором switch() и в зависимости от значения выполниться та или иная функция.
Каждая операция, предлагаемая пунктами меню, выполняется соответствующей функцией.
'c' - Вычислить уравнение...................... calculate_differential_equation(); 'p' - Вывести информацию о вычислениях........................... debug.print();
'w' - Запись вычислений в файл........................................... debug.write();
'q' - Выход - инструкцией.............................................................. return 0;
В функции формирования нового списка calculate_differential_equation():
Происходит вычисление дифференциального уравнения численными4
методами согласно поставленной задаче.
В вызове метода объекта debug.print():
Выводим все информацию о вычислениях на дисплей.
6. ИСХОДНЫЙ МОДУЛЬ ПРОГРАММЫ
/* Исходный текст программы main.cpp */
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cctype>
#include <cmath>
using namespace std;
// typedef для обратного вызова степенного уравнение
// таким образом можно использовать много различных уравнений
typedef double (*callback_exponential_equation)(double);
// ссылка на процедуру дифференциального уравнения
typedef double (*callback_differential_equation)(double, double);
// уравнение по которому узнаем наименьший положительный корень k
// для подстановки его в диффиринциальное уравнение
double exponential_equation(double);
// дифференциальное уравнение
double differential_equation(double, double);
// решение уравнения методом половиннго деления
double method_half_division(callback_exponential_equation);
// функция расчета дифференциального уравнения
void calculate_differential_equation();
double k; // параметр используемый в дифференциальном уравнении
const double h = 0.1; // шаг
const double e = 0.0001; // точность вычисления
// вспомогательные функции/классы
int menu();
char buffer[120];
// позволяют записывать и выводить данные о вычислениях
struct Stack {
char data[120];
Stack *next;
Stack(char *str) { strcpy(data, str); next = NULL; }
~Stack() { delete next; }
};
struct Queue {
Stack *head;
Stack *tail;
};
// класс отладчика
// позволяет собирать информацию о вычислениях
// выводит данные на дисплей или сохраняет их в текстовый файл
class Debug {
Queue list;
public:
Debug() { list.head = list.tail = NULL; }
~Debug() { if (!empty()) clean(); }
void insert(char*);
void print();
void write();
void clean() { delete list.head; list.head = list.tail = NULL; }
bool empty() { return (list.head!= NULL)? true: false; }
};
Debug debug; // отладчик
int main()
{
int choice;
for (;;) {
choice = menu();
switch (choice) {
case 'c':
// очистить все сообщения отладки
if (!debug.empty())
debug.clean();
calculate_differential_equation();
debug.print();
break;
case 'p':
debug.print();
case 'w':
debug.write();
break;
case 'q':
return 0;
}
}
}
double exponential_equation(double x)
{
return pow(x, 5) - pow(x, 3) - 3;
}
double method_half_division(callback_exponential_equation f)
{
double a, b, c, h;
int i;
a = b = c = 0.0;
// введем шаг для отрезка
h = 1;
i = 0;
debug.insert("----------------------------------------------------");
debug.insert("Поиск корня уравнения методом половинного деления...");
debug.insert("Поиск отрезка для нахождения корня уравнения...");
// поиск отрезка, на котором функция меняет знак
while (!(f(a)*f(b) < 0)) {
a -= h;
b += h;
sprintf(buffer, "a=%.2f b=%.2f", a, b);
debug.insert(buffer);
}
sprintf(buffer, "Результат: a=%.2f b=%.2f", a, b);
debug.insert(buffer);
debug.insert("Поиск корня до заданной точности...");
do {
i++;
c = (a + b) / 2;
sprintf(buffer, "a=%f b=%f (b - a)/2=%f", a, b, (b - a)/2);
debug.insert(buffer);
if ((f(a) * f(c)) < 0) {
b = c;
}
else {
a = c;
}
} while (((b - a) / 2) > e);
sprintf(buffer, "Центр отрезка[a;b] c=%f", c);
debug.insert(buffer);
sprintf(buffer, "(b - a)/2=%f < e=%f\nВыход из цикла.", (b - a)/2, e);
debug.insert(buffer);
sprintf(buffer, "Кол-во операций: %d", i);
sprintf(buffer, "Результат: k=%f", c);
debug.insert(buffer);
return c;
}
double differential_equation(double x, double y)
{
return (cos(y) / (k + x)) + y;
}
void calculate_differential_equation()
{
int n; // кол-во элементов в массивах значений
int i; // счетчик
double *x_val; // массив значений переменной
double *y_val; // массив значений функции
// ссылка на функцию дифференциального уравнения
// используется чисто ради удобства написания алгоритма вычисления
callback_differential_equation f = differential_equation;
// по заданию дано 11 элементов - 0,1,2,...,10
// для y(0), y(0.1),...,y(1)
n = 11;
x_val = new double[n];
y_val = new double[n];
// расчет параметра k в дифференциальном уравнении
// k - это положительное наименьшее значение корня уравнения
// описаного в функции exponential_equation
// exponential_equation - передается ссылка на функцию в качестве указателя на неё
k = method_half_division(exponential_equation);
// начальное значение функции при x = 0
y_val[0] = 0.1;
// инициализация значений переменной
for (int i = 0; i < n; i++)
x_val[i] = h * i;
// непосредственно расчеты дифференциального уравнения методом
// Рунге-Кутта второго порядка с коррекцией в средней точке
for (i = 0; i < n - 1; i++)
y_val[i+1] = y_val[i] + h * f((x_val[i] + h/2), (y_val[i] + h/2 * f(x_val[i], y_val[i])));
debug.insert("----------------------------------------------------");
debug.insert("Вычисление дифференциального уравнения Рунге-Кутта");
debug.insert("второго порядка с коррекцией в средней точке.");
sprintf(buffer, "Шаг h=%.2f", h);
debug.insert(buffer);
debug.insert("Таблица решений:");
for (int i = 0; i < n; i++) {
sprintf(buffer, "y(%.1f)=%f", x_val[i], y_val[i]);
debug.insert(buffer);
}
delete[] x_val, y_val;
}
// иеню приложения
int menu()
{
char ch;
do {
cout << "\n";
cout << "Меню приложения:\n";
cout << "Вычислить (C)alculate;\n";
cout << "Отобразить результаты (P)rint;\n";
cout << "Сохранить результаты в файл (W)rite;\n";
cout << "Выйти (Q)uit;\n";
cout << "Выбрать: ";
cin >> ch;
} while (!strchr("qpwc", tolower(ch)));
return tolower(ch);
}
void Debug::insert(char *data)
{
Stack *p;
p = new Stack(data);
if (list.head!= NULL)
list.tail->next = p;
else
list.head = p;
list.tail = p;
}
void Debug::write()
{
Stack *p;
ofstream log_file;
p = list.head;
cout << "Сохраненние информации в файл...\n";
log_file.open("main.log");
while (p!= NULL) {
log_file << p->data << "\n";
p = p->next;
}
log_file.close();
}
void Debug::print()
{
Stack *p;
p = list.head;
cout << "Информация о вычислениях:\n";
while (p!= NULL) {
cout << p->data << "\n";
p = p->next;
}
cout << "\n";
}
7. РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ ВЫПОЛНЕНИЯ ЗАДАНИЯ
Рис. 7.1
8. СПИСОК ЛИТЕРАТУРЫ
1. Численные методы // Учебник для сред. спец. учеб. заведений / Н.И. Данилина, Н.С. Дубровская, О.П. Кваша и др. - М.: "Высшая школа", 1976. - 368с.
2. Демидович Б.П., Марон И.А. Основы вычислительной математики. М.: "Наука", изд. IV, 1970.
3. Демидович Б.П., Марон И.А., Шувалова Э.З. Численные методы анализа. Физматгиз, изд. III, 1967.
4. Копченова Н.В., Марон И.А. Вычислительная математика в примерах и задачах. М.: "Наука", 1972.
5. Марон И.А. Вычислительная математика. Выпуск 1-3, М., изд. ВЗЭИС, 1979.
6. Марон И.А. Вычислительный лабораторный практикум. М., изд. ВЗЭИС, 1979.
7. Заварыкин В.М. Численные методы. - 1990.
8. Каранчук В.П. и др. Основы применения ЭВМ: Учебн. Пособие для вузов / В.П.Каранчук, И.Н.Сваровский, И.Д.Суздальницкий. - М.: Радио и связь, 1988.- 288с.
Дата добавления: 2015-08-29; просмотров: 18 | Нарушение авторских прав
<== предыдущая лекция | | | следующая лекция ==> |
3. 2. Налоговый контроль. Налоговые проверки 5 страница | | | Основным принципом, действующим при реализации иностранными лицами права на судебную защиту, является принцип национального режима. В соответствии с этим принципом иностранцы имеют право обращаться |