Численное дифференцирование

Методы численного дифференцирования. Вычисление производной, простейшими формулами. Численное дифференцирование, основанное на интерполяции алгебраическими многочленами. Аппроксимация многочленом Лагранжа. Дифференцирование, с использованием интерполяции.

Рубрика Математика
Вид курсовая работа
Язык русский
Дата добавления 15.02.2016
Размер файла 1,3 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на Allbest.ru

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовой работе

по дисциплине «Вычислительная математика»

на тему «Численное дифференцирование»

Введение

В современных науке и технике важную роль играет математическое моделирование, заменяющее эксперименты с реальными объектами экспериментами с их математическими моделями. Но для практических задач довольно редко удается найти аналитическое решение уравнений, составляющих математическую модель явления. Поэтому приходится применять численные методы.

Численное решение прикладных задач всегда интересовало математиков. Резкий скачок в развития вычислительной техники положил начало бурному развитию численных методов.

Численные методы представляют собой набор алгоритмов, позволяющих получать приближенное численное решение поставленных математических задач. Как и любой другой численный метод, эти методы позволяют с заданной точностью получить нужные результаты, используя заданные алгоритмы, не прибегая к выполнению аналитических преобразований над входными данными. Одной из подзадач численных методов, является численное дифференцирование. Численное дифференцирование облегчает работу в случае, если выполнение аналитических преобразований достаточно трудоёмко или же исходные данные, то есть функция, подлежащая дифференцированию, представляет собой результаты проведения экспериментов. Кроме того, численное дифференцирование широко используется при разработке численных методов решения многих задач (решение дифференциальных уравнений, поиск решений не линейных уравнений, поиск точек экстремума функции и др.).

1. Обзор методов численного дифференцирования

1.1 Вычисление производной, используя простейшие формулы

Предположим, что функция f дифференцируема в окрестности точки х достаточное количество раз[1]. Исходя из определения производной:

можно получить две простейшие приближенные формулы:

где h - малый параметр (шаг).

Эти формулы часто называют правой и левой разностными производными.

Оценка погрешностей данных формулы производится по следующей формуле:

где

где - точка, принадлежащая промежутку ).

Таким образом, формулы левых и правых разностных производных имеют первый порядок точности.

Для вычисления второй производной данным методом применяется следующая формула:

Данную величину также называют второй разностной производной.

Для вычисления погрешности, воспользуемся соответствующим разложением по формуле Тейлора:

отсюда получаем:

Тогда для оценки погрешности можно использовать следующее неравенство:

Таким образом вторая разностная производная имеет второй порядок точности.

Приведенные формулы численного дифференцирования имеют простую геометрическую интерпретацию. На рисунке 1.1 a) изображен график функции и отмечены точки N-, N0 и N+, с координатами (x-h, f(x-h)), (x,f(x)) и (x+h,f(x+h)) соответственно.

Рисунок 1.1 - Графики функций

Производная f'(x) равна tg() относительно оси Ox в точке N0. Тангенс угла наклона прямых N- N0 и N+ N0, близок к значению производной в точке х. Однако можно заметить, что тангенс прямой N- N+, которая изображена на рисунке 1.1 б), более близок к искомому значению.

Логично предположить, что можно использовать тангенс прямой N- N+ для более точного нахождения производной в указанной точке. Получившаяся формула выглядит следующим образом:

Данную формулу также называют центральной разностной производной.

Для определения погрешности используют следующую формулу:

где

Формула имеет вторую степень точности.

Таким образом можно получить формулы любой точности, однако для этого нужно знать значения функции в большем количестве точек.

Например, формула, имеющая четвертый порядок, точности имеет следующий вид:

Данный способ удобен в тех случаях, когда точка лежит на заданных узлах, но вычислить производную точки, не принадлежащей узлам, не предоставляется возможным.

1.2 Численное дифференцирование, основанное на интерполяции алгебраическими многочленами

Предположим, что f(x) в окрестности точки x аппроксимируется некоторой другой функцией g(x), и производная g'(x) легко вычисляется[2]. Тогда:

Пусть Pn(x) - интерполяционный многочлен n-ой степени с узлами интерполяции x0 < x1<x2<…<xn. В таком случае:

Для получения интерполяционного многочлена применяется аппроксимация многочленом Лагранжа.

Для получения полинома Лагранжа используется следующая формула:

где l0,l1…ln - многочлены, зависящие от x0,x1…xn.

Неизвестные многочлены находятся по формуле:

Таким образом можно записать компактно формулу полинома Лагранжа:

Если использовать данную формулу для получения полинома первой степени, получится следующее выражение:

Из данного выражения можно получить другой алгоритм для интерполяции.

В общем случае полином имеет следующую форму:

Используя это выражение, составим систему линейных алгебраических уравнений, следующего вида:

Решением данной системы будут коэффициенты при соответствующих степенях полинома.

1.3 Обусловленность численного дифференцирования

Несмотря на внешнюю простоту формул численного дифференцирования, их применение требует особой осторожности[3]. Отметим, что используемые при численном дифференцировании значения функции не в узловых точках содержат ошибки. Поэтому к погрешности формул численного дифференцирования добавляется не устранимая погрешность, вызванная погрешностями вычисления функции. Для того, что бы погрешность аппроксимации была достаточно малой, требуется очень маленькое значение шага h. Однако, при малых шагах формулы численного дифференцирования становятся плохо обусловленными и результат их применения может быть полностью искажен неустранимой ошибкой. Действительная причина этого явления лежит не в несовершенстве предложенных методов вычисления производных, а в некорректности самой операции дифференцирования приближенно заданной функции.

В качестве примера приведем формулу правой разностной производной.

Полная погрешность

представляет собой сумму погрешностей аппроксимации

и не устранимой погрешности

Пусть = | f(x) - f*(x)| - верхняя граница абсолютной погрешности. Тогда погрешность оценивается следующим образом:

Эта оценка означает, что чувствительность формулы к погрешностям входных данных характеризуется абсолютным числом обусловленности

Так как при , то формула дифференцирования становится очень плохо обусловленной. Поэтому, несмотря на то, что погрешность аппроксимации стремится к нулю, следует ожидать, что полная погрешность будет неограниченно возрастать. Во всяком случае так себя ведет верхняя граница полной погрешности

Таким образом, при использовании формул для вычисления производной функции f, заданном с погрешностью, следует обратить внимание на выбор шага. Однако даже при оптимальном выборе шага полная погрешность окажется величиной, пропорциональной лишь (для формулы правой разностной производной).

Формулы для вычисления производных высших порядков обладают еще большей чувствительностью к ошибкам задания функции. Поэтому значения производных высокого порядка с помощью данных методов, могут быть очень не точными.

Производная находит широкое приложение в физике для нахождения скорости по известной функции координаты от времени, ускорения по известной функции скорости от времени; для нахождения наибольших и наименьших величин.

Производная является важнейшим инструментом экономического анализа, позволяющим углубить геометрический и математический смысл экономических понятий, а также выразить ряд экономических законов с помощью математических формул.

Наиболее актуально использование производной в предельном анализе, то есть при исследовании предельных величин (предельные издержки, предельная выручка, предельная производительность труда или других факторов производства и т. д.).

Производная применяется в экономической теории. Многие, в том числе базовые, законы теории производства и потребления, спроса и предложения оказываются прямыми следствиями математических теорем

Если сравнивать описанные способы численного дифференцирования, то можно заметить, что методы левой, центральной и правой разностей довольно просто реализуются, на их выполнение требуется меньше ресурсов и времени. Однако, дифференцирование с помощью замены функции интерполяционным многочленом позволяет узнать значении производной в точках, отличных от узловых, но этот метод имеет большие затраты времени. К тому же, при маленьких значения шага h и увеличения кол-ва данных шагов значительно повышается погрешность, хотя и находится многочлен, который более приближен к функции.

2. Математическая постановка задачи численного дифференцирования

2.1 Разностные формулы численного дифференцирования

Для нахождения производной данным способом необходимо установить, к какому узлу принадлежит искомая точка. Возможные варианты: искомый узел крайний правый, искомый узел крайний левый, искомый узел не является крайними. Дальше, в зависимости от узла, необходимо применить определенную формулу.

Входные данные:

Множество точек Mat = такое, что

а) .

б)

Точка, в которой нужно найти производную: .

Выходные данные:

Значение производной в указанной точке:

Аналитическое решение:

Использования конкретной формулы зависит от того, где находится точка, производную которой нужно вычислить. Если это точка крайняя слева, то используется первая формула, если точка крайняя справа, то используется вторая формула, в остальных случаях используется третья формула.

Алгоритм дифференцирования методом конечных разностей:

1) Найти .

2) PointInd = i.

3)

4) Если i = 0, тогда .

5) Если i = n, тогда

6) Если тогда .

Графическое представление алгоритма:

На рисунке 2.1 изображена блок-схема алгоритма дифференцирования с использованием разностных формул.

Рисунок 2.1 - Блок-схема функции вычисления производной методом разностей

2.2 Численное дифференцирование, с использованием интерполяции

Для решения задачи данными методом необходимо найти интерполяционный многочлен Лагранжа. Для его поиска составляется специальная система уравнений, решением которой являются коэффициенты при соответствующих степенях многочлена. В дальнейшем данный многочлен дифференцируется. Подставляя заданную точку в многочлен, получившийся после дифференцирования, получаем примерное значение производной в данной точке.

Входные данные:

Точка, в которой нужно найти производную: .

Множество точек Mat =такое, что

.

Выходные данные:

Значение производной в указанной точке:

Аналитическое решение:

Алгоритм дифференцирования с использованием полинома Лагранжа:

1) Для матрицы для .

2) для

3) Решаем систему уравнений , относительно .

4)

5) Заполнить массив . Для делать

6) Для делать

7)

Графическое представление алгоритма:

На рисунке 2.2 изображена блок-схема алгоритма дифференцирования с использованием полинома Лагранжа.

Рисунок 2.2 - Блок-схема алгоритма решения поставленной задачи

3. Тестирование разработанной программы

На рисунке 3.1 представлена работа программы на одном из тестов.

Рисунок 3.1 - Работа программы во время второго теста

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

Тестирования производилось для следующих функций:

Результаты тестов представлены в таблицах 3.1, 3.2, 3.3, и 3.4.

Первые два столбца таблицы - это точка х и значение производной в данной точке, полученное аналитически, соответственно. Следующие два столбца - значение производной, вычисленных с помощью формул численного дифференцирования (

). Следующие два столбца - погрешность вычисленных значений. Последние два столбца - среднее время работы методов, измеряемое в тактах процессора.

Результаты теста, при котором использовалась функция представлены в таблице 3.1. Аналитически полученная формула производной:

Таблица 3.1 - Первый тест программы

x

0

1

0,90032

1,16401

0,09968

-0,16401

4925

18100

0,78539

0,70710

0,63663

0,63663

0,07047

0,07047

5660

18400

1,57079

0

0,37294

0,10925

-0,37294

-0,10925

5140

17143

По результату первого теста можно заметить, что точность методов колеблется в различных точках. Формулы разностных производных работают быстрее полиномиальной интерполяции примерно в 3.4 раза быстрее.

Второй тест был проведен с использованием функции Производная данной функции задается следующей формулой: Результаты теста представлены в таблице 3.2. В данном тесте функция задавалась четырьмя точками.

Таблица 3.2 - Второй тест программы

x

-1

-2

-1

-2

-1

0

5350

21400

0

0

0

0

0

0

4910

20000

1

2

2

0

2

0

4800

22650

2

4

3

1

4

0

4900

20550

В данном тесте интересно то, что с помощью полиномиальной интерполяции функция была найдена точно, поэтому погрешность производной равна 0. При других опытах было замечено, что, если функция изначально была полиномом, то этот полином часто находится точно, или же он получается близким к исходному. При использовании разностных формул в крайних точках была получена довольно большая погрешность, а вот в остальных точках погрешность отсутствует. При данных теста было получено, что скорость разностных формул быстрее примерно в 4 раза.

При третьем тесте была использована функция Ее производная совпадает с самой функцией. Было использовано 5 точек. Результаты тестирования представлены в таблице 3.3.

Таблица 3.3 - Третий тест программы

x

0,2

1,2214

1,3521

1,22092

-0,1307

0,00048

5470

24550

0,4

1,49182

1,50178

1,49192

-0,01005

-0,0001

4700

25200

0,6

1,82211

1,8343

1,82203

-0,01219

0,00008

5150

24000

0,8

2,22554

2,24043

2,22574

-0,01489

-0,0002

5100

24000

1

2,71828

2,4637

2,71755

0,25458

0,00073

5300

23800

В третьем тесте погрешность метода, использующего полиномиальную интерполяцию, во много раз меньше, чем разностных формул. В данном тесте метод разностной производной быстрее в 4.7 раза. последнем тесте была использована следующая функция: . Производная этой функции выглядит так: В программе функция была задана шестью точками. Результаты теста в таблице 3.4.

Таблица 3.4 -Четвертый тест программы

x

-1

-0,36787

-0,43248

-0,17795

0,06461

-0,18992

5000

28900

-0,5

-0,45489

-0,36787

-0,49623

-0,08702

0,04134

5200

27800

0

0

0,26055

0,02263

-0,26055

-0,02263

4750

29300

0,5

2,0609

2,71828

2,03589

-0,65738

0,02501

5550

30330

1

8,15484

9,67162

8,21011

-1,51678

-0,05527

5050

32200

1,5

23,52886

14,73104

23,22028

8,79782

0,30858

5900

33900

Последний тест отличался от предыдущих тем, что функция была сложной, а не элементарной. В данном тести по мере роста функции погрешность формулы разностей увеличивалась на много быстрее. Но так же данная формула оказалась быстрее уже в 5.8 раза.

На рисунке 3.2 показан график зависимости отношения от количества заданных точек.

Рисунок 3.2 - График зависимости от количества точек

Из графика видно прямую зависимость от количества заданных точек.

На основании данных тестов можно сделать вывод, что разностные формулы численного дифференцирования в большинстве случаев менее точны, чем использование интерполяционного полинома Лагранжа, однако они работают значительно быстрее.

Также были проведены тесты, когда были введены неверные входные данные (различные значения функции в одинаковых точках, данные, не соответствующие формату и др.). Во время этих тестов ошибок, приводящих к не правильному решению или экстренному завершению программы, обнаружено не было.

Заключение

численный дифференцирование многочлен интерполяция

В результате проделанной работы были изучены следующие методы численного дифференцирования: формулы разностных производных, дифференцирования с помощью интерполяционного многочлена Лагранжа.

У каждого метода были выявлены сильные и слабые стороны.

Сильной стороной формул разностных производных является быстрота их выполнения. Однако данные формулы не могут рассчитывать производные в точках, отличных от узловых. Также, на основанию проведенных опытов было установлено, что данные формулы обычно имеют меньшую точность.

Дифференцирование с использование интерполяционного многочлена Лагранжа позволяет находить значение производной в точках, отличных от узловых. Также имеет в большинстве случаев большую точность. Если известно, что функция должна представлять полином, то погрешность метода стремится к нулю. Однако, данный метод требует больших вычислительных затрат, т.к. требуется решать систему уравнений, возводить числа в степень.

Был составлен алгоритм решения задачи различными способами.

На основании алгоритмов была составлена программа, реализующая данные методы.

В ходе тестов программы не было обнаружено критических ошибок.

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

Список литературы

1 А.А.Амосов, Ю.А.Дубинский, Вычислительные методы для инженеров. -- М.: Высш.шк., 2014. - с.544

2 David Kincaid and Ward Cheney, Numerical analysis: mathematics of scientific computing. -- Wadsworth, Inc., Belmont, California, 2011. - с.701

3 Н. С. Бахвалов, Численные методы. -- М.: Наука, 2009. - с.190

Приложения

Приложение А

Текст программы

Модуль Form1.cs:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Diagnostics;

namespace Kursavik_sem_3

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

IDiffer dif;

RaznDiffer Razn;

InterDiffer Interp;

Form2 form2;

private void Form1_Load(object sender, EventArgs e)

{

//задачем начальные значения программы

this.Text = "The programm";

listBox1.Items.Add("0,2 1,2214");

listBox1.Items.Add("0,4 1,49182");

listBox1.Items.Add("0,6 1,82211");

listBox1.Items.Add("0,8 2,22554");

listBox1.Items.Add("1,0 2,71828");

Razn = new RaznDiffer(label8);

Interp = new InterDiffer(label8);

dif = Razn;

comboBox1.SelectedItem = 0;

comboBox1.SelectedIndex = 0;

label1.ResetText();

form2 = new Form2(this);

panel1.Invalidate();

}

private void button1_Click(object sender, EventArgs e)

{

label8.ResetText();

decimal x, y;

try

{

//если значения нормально конвернтируются

//то добавляем их к другим точкми

x = Convert.ToDecimal(textBox1.Text);

y = Convert.ToDecimal(textBox2.Text);

string strX, strY;

strX = Convert.ToString(x);

strY = Convert.ToString(y);

listBox1.Items.Add(x+" "+y);

}

catch(FormatException)

{

MessageBox.Show("Invalid data!\nPlease, enter other data.", "Error converting");

}

}

private void button2_Click(object sender, EventArgs e)

{

try

{

ListBox.SelectedObjectCollection col = listBox1.SelectedItems;

while (col.Count!=0)

{

listBox1.Items.Remove(col[0]);

}

}

catch (ArgumentOutOfRangeException)

{

MessageBox.Show("None selected", "Error");

}

}

private void textBox1_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyValue == 13) button1_Click(this, e);

}

private void StrDiv(string str, out decimal x, out decimal y)

{

//разбираем строку на состовляющие числа.

string strF="";

int i = 0;

while (str[i] != ' ') strF += str[i++];

x = Convert.ToDecimal(strF);

strF = "";

while (i < str.Length) strF += str[i++];

y = Convert.ToDecimal(strF);

}

private void button3_Click(object sender, EventArgs e)

{

decimal x1;

try

{

x1= Convert.ToDecimal(textBox3.Text);

}

catch (FormatException)

{

MessageBox.Show("Invalid data!\nPlease, enter other data.", "Error converting");

return;

}

int N = listBox1.Items.Count;

decimal[,] mat = new decimal[2, N];

//перводим listBox в массив чисел

for (int i = 0; i < N; i++)

{

decimal x, y;

string s = listBox1.Items[i].ToString();

StrDiv(s, out x, out y);

mat[0, i] = x;

mat[1, i] = y;

}

//сортируем массив по Х

//за одно проверяем на наличие одинаковых точек

for (int i=0; i<mat.GetLength(1)-1; i++)

for (int j = i+1; j < mat.GetLength(1); j++)

{

if (mat[0, i] == mat[0, j])

{

label1.Text = String.Format(

"Error points: \nx={0:F5}; y={1:F5}\nx={2:f5}; y={3:f5}",

mat[0,i],mat[1,i],mat[0,j],mat[1,j]);

return;

}

decimal buf1,buf2;

if (mat[0, i] > mat[0, j])

{

buf1 = mat[0, i]; buf2 = mat[1, i];

mat[0, i] = mat[0, j]; mat[1, i] = mat[1, j];

mat[0, j] = buf1; mat[1, j] = buf2;

}

}

//находим проихводную, если это возможно

if (dif.isSolve(mat, x1))

{

//timer для подчета тактов процессора

Stopwatch timer = new Stopwatch();

timer.Start();

label1.Text = String.Format("f'(x) = {0:F5}", dif.Solve(mat, x1));

dif.ShowAnswer();

timer.Stop();

label8.Text += String.Format("\nTime: {0} ticks.", timer.ElapsedTicks);

panel1.Invalidate();

}

else label1.Text = "Нет решения";

}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)

{

//переключаем интерфейсную ссылку на нужный режим

if (comboBox1.SelectedIndex == 0) dif = Razn;

else dif= Interp;

}

private void panel1_Paint(object sender, PaintEventArgs e)

{

BufferedGraphics buffer;

BufferedGraphicsContext context;

context = BufferedGraphicsManager.Current;

context.MaximumBuffer = new System.Drawing.Size(panel1.Width + 1, panel1.Height + 1);

Rectangle rec = new Rectangle(0, 0, panel1.Width, panel1.Height);

buffer = context.Allocate(e.Graphics, rec);

//ТУТ ДОЛЖНА БЫТЬ ОТРИСОВКА КООДРИНАТНОЙ СЕТКИ

//И графика из точек

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

int zoom = form2.trackBar1.Value;

Font font = new System.Drawing.Font("Arial", 6);

//используемые кисти

Pen pen = new Pen(Color.Black); //для секти

Pen penRed = new Pen(Color.Red);//для графика по точкам

//используемые заливки

Brush brush = new SolidBrush(Color.Black); //для сетки

//Отрисовка системы коодринат

buffer.Graphics.Clear(Color.White);

int Xs = (int)(form2.x*zoom);

int Ys = (int)(form2.y * zoom);

float maxX = panel1.Width / 2 ;

float maxY = panel1.Height / 2 ;

buffer.Graphics.TranslateTransform(maxX-Xs, maxY+Ys);

//рисуем оси Х и Y, а так же разметку

buffer.Graphics.DrawLine(pen, 0, maxY-Ys, 0, -maxY-Ys);

buffer.Graphics.DrawLine(pen, maxX+Xs, 0, -maxX+Xs, 0);

//int stepX =

int StepM = panel1.Width / zoom;

int StepMin = (int)(maxX - Xs)/zoom;

for (int j = 0; j < StepM; j++)

{

int i = j-StepMin;

if (i == 0) continue;

buffer.Graphics.DrawLine(pen, i * zoom, 3f, i * zoom, -3f);

buffer.Graphics.DrawString(String.Format("{0}", i), font, brush, i * zoom, -12f);

}

StepM = panel1.Height / zoom;

StepMin = (int)(maxY + Ys) / zoom;

for (int j = 0; j < StepM; j++)

{

int i = j - StepMin;

buffer.Graphics.DrawLine(pen, 3f, i * zoom, -3f, i * zoom);

buffer.Graphics.DrawString(String.Format("{0}", -i), font, brush, -12f, i * zoom);

}

PointF[] p1 = new PointF[3];

p1[0] = new PointF(0f, -(float)(maxY + Ys));

p1[1] = new PointF(4f, -(float)(maxY + Ys) + 10f);

p1[2] = new PointF(-4f, -(float)(maxY + Ys)+ 10f);

buffer.Graphics.DrawString("Y", font, brush, 12f, -(maxY + Ys));

buffer.Graphics.FillPolygon(brush, p1);

p1[0] = new PointF((float)maxX+Xs, 0f);

p1[1] = new PointF((float)(maxX+Xs)- 10f, 4f);

p1[2] = new PointF((float)(maxX +Xs) - 10f, -4f);

buffer.Graphics.DrawString("X", font, brush, (maxX + Xs) - 12f, 12f);

buffer.Graphics.FillPolygon(brush, p1);

//конец отрисовки коодринат

//Начинаем сторить график.

int N = listBox1.Items.Count;

PointF[] points = new PointF[N];

for (int i = 0; i < N; i++)

{

decimal x, y;

string s = listBox1.Items[i].ToString();

StrDiv(s, out x, out y);

points[i].X = (float)x*zoom;

points[i].Y = -(float)y*zoom;

}

for (int i=0; i<N-1; i++)

for (int j = i+1; j < N; j++)

{

if (points[i].X == points[j].X)

{

label1.Text = String.Format(

"Error points: \nx={0:F5}; y={1:F5}\nx={2:f5}; y={3:f5}",

points[i].X, points[i].Y, points[j].X, points[j].Y);

return;

}

PointF buf;

if (points[i].X > points[j].X)

{

buf = points[i];

points[i] = points[j];

points[j] = buf;

}

}

for (int i = 0; i < N; i++)

{

buffer.Graphics.DrawLines(penRed, points);

}

//построили график

//сторим полином, если активирован нужный режим

dif.Paint(buffer, zoom);

//построили, если что))

//Выводим на экран, что получилось)

buffer.Render(e.Graphics);

//и очищаем память

buffer.Dispose();

}

private void graficToolStripMenuItem_Click_1(object sender, EventArgs e)

{

form2.Show();

}

private void Form1_ClientSizeChanged(object sender, EventArgs e)

{

panel1.Invalidate();

}

private void textBox3_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyValue == 13) this.button3_Click(this, e);

}

}

}

Модуль From2.cs:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace Kursavik_sem_3

{

public partial class Form2 : Form

{

public float x;

public float y;

Form1 mainForm;

public Form2()

{

InitializeComponent();

}

public Form2(Form1 ptr)

{

mainForm = ptr;

InitializeComponent();

this.Text = "Grafic";

x = 0;

y = 0;

}

private void trackBar1_Scroll(object sender, EventArgs e)

{

mainForm.panel1.Invalidate();

}

private void Form2_Load(object sender, EventArgs e)

{

this.Text = "Grafic";

}

private void textBox1_TextChanged(object sender, EventArgs e)

{

try

{

x = Convert.ToSingle(textBox1.Text);

y = Convert.ToSingle(textBox2.Text);

mainForm.panel1.Invalidate();

}

catch (FormatException)

{

textBox1.Text = Convert.ToString(x);

textBox2.Text = Convert.ToString(y);

MessageBox.Show("Invalid data!\nPlease, enter other data.", "Error converting");

}

}

private void textBox1_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyValue == 13) this.textBox1_TextChanged(this, e);

}

private void Form2_FormClosing(object sender, FormClosingEventArgs e)

{

e.Cancel = true;

this.Hide();

}

}

}

Модуль Differ.cs:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

using System.Windows.Forms;

namespace Kursavik_sem_3

{

//интерфейс для работы с разными методами

interface IDiffer

{

//метод проверяет возможность решения

bool isSolve(decimal[,] matrix, decimal point);

//метод находит производную

decimal Solve(decimal[,] matrix, decimal point);

//метод рисует на графике что-то если это нужно

void Paint(BufferedGraphics buffer, int zoom);

//показывает решение

void ShowAnswer();

}

//метод разностных производных

class RaznDiffer :IDiffer

{

decimal yL, yR, y, h;

bool R, L, C; //используемый метод(для ShowAnsewr)

Label lab; //куда выводить

public RaznDiffer(Label l)

{

lab = l;

}

public bool isSolve(decimal[,] matrix, decimal point)

{

if (matrix.GetLength(0) != 2) return false;

bool PointFind = matrix[0, 0] == point; ;

bool StepRight = true;

decimal step = matrix[0, 1] - matrix[0, 0];

for (int i = 1; i < matrix.GetLength(1); i++)

{

//проверям равномерность сетки

//а также наличие данной точки в массиве

decimal s = matrix[0, i] - matrix[0, i - 1];

if (Math.Abs(step-s)>0.0000001M)

{

StepRight = false;

break;

}

if (matrix[0, i] == point) PointFind = true;

}

return PointFind&&StepRight;

}

public decimal Solve(decimal[,] matrix, decimal point)

{

int pointInd=0;

int N=matrix.GetLength(1);

decimal h = matrix[0, 1] - matrix[0, 0];

//ищем номер точки для дифференцирования

for (int i=0; i<N; i++)

if (point == matrix[0, i])

{

pointInd = i;

break;

}

//используем формулы, в зависимости

//от найденой точки

if (pointInd == 0)

{

R = true;

L = C = false;

y = matrix[1, 0];

yR = matrix[1, 1];

this.h = h;

return (matrix[1, 1] - matrix[1, 0])/h;

}

if (pointInd == N - 1)

{

L = true;

R = C = false;

y = matrix[1, pointInd];

yL = matrix[1, pointInd - 1];

this.h = h;

return (matrix[1, pointInd] - matrix[1, pointInd-1]) / h;

}

if (pointInd != 0 && pointInd != N - 1)

{

C = true;

R = L = false;

yR = matrix[1, pointInd + 1];

yL = matrix[1, pointInd - 1];

this.h = h;

return (matrix[1, pointInd + 1] - matrix[1, pointInd - 1]) / (2 * h);

}

return 0;

}

public void Paint(BufferedGraphics buffer, int zoom)

{

//тут не нужно ничего рисовать

}

public void ShowAnswer()

{

lab.ResetText();

//выводим текст в зависимости от точки

if (R) lab.Text = String.Format("f'(x) = ({0:f5}-{1:f5})/{2:F5}", yR, y, h);

if (L) lab.Text = String.Format("f'(x) = ({0:f5}-{1:f5})/{2:F5}", y, yL, h);

if (C) lab.Text = String.Format("f'(x) = ({0:f5}-{1:f5})/{2:F5}", yR, yL, 2*h);

}

}

//с использованием интерполяции

class InterDiffer : IDiffer

{

//набор точек и значений

//используемых в предыдущй раз

decimal[,] interMat;

//получившаяся фукнция

decimal[] intrFunc;

//производная функиции

decimal[] difPolinom;

Label lab;

bool CompareMat(decimal[,] matrix)

{

//метод сравнивает 2-е матрицы

if (matrix.GetLength(0) != interMat.GetLength(0)) return false;

if (matrix.GetLength(1) != interMat.GetLength(1)) return false;

for (int i = 0; i < matrix.GetLength(0); i++)

for (int j = 0; j < matrix.GetLength(1); j++)

if (matrix[i, j] != interMat[i, j]) return false;

return true;

}

void CreateMatInterol(decimal[,] matrix)

{

//метод сторит матрицу,

//необходимую для получения полинома

int N = matrix.GetLength(0);

for (int i = 0; i < N; i++)

{

for (int j = 0; j < N; j++)

{

if (j == 0)

{

matrix[i, j] = 1;

continue;

}

matrix[i, j] = matrix[i, j - 1] * interMat[0, i];

}

}

for (int i = 0; i < N; i++) matrix[i, N] = interMat[1, i];

}

public InterDiffer() { }

public InterDiffer( Label lab)

{

this.lab = lab;

}

public bool isSolve(decimal[,] matrix, decimal point)

{

if (matrix.GetLength(0) != 2) return false;

return true;

}

public decimal Solve(decimal[,] matrix, decimal point)

{

//сравниваем матрицы, если они одинаковые

//то расчитывать полином заново не нужно

if (interMat==null ||!CompareMat(matrix) )

{

interMat = matrix;

int N = matrix.GetLength(1);

decimal[,] iMat = new decimal[N,N+1];

decimal[] ans = new decimal[N];

decimal[] dif = new decimal[N-1];

//создаем матрицу для решения

CreateMatInterol(iMat);

//и решаем ее

MathBase.GetSolve(iMat, ans);

//а потом берем производную от решения

MathBase.GetDifferPolinom(ans, dif);

intrFunc = ans;

difPolinom = dif;

}

return MathBase.Fx(difPolinom,point);

}

public void Paint(BufferedGraphics buffer, int zoom)

{

Pen penRed = new Pen(Color.SeaGreen);

float minX = (float)interMat[0, 0];

float maxX = (float)interMat[0, interMat.GetLength(1) - 1];

for (float x = -1f; x < maxX; x += 0.01f)

buffer.Graphics.DrawLine(penRed, x * zoom,

-(float)MathBase.Fx(intrFunc, (decimal)x) * zoom,

(x + 0.01f) * zoom,

-(float)MathBase.Fx(intrFunc,(decimal)(x + 0.01f)) *zoom);

}

public void ShowAnswer()

{

lab.ResetText();

lab.Text = "Interpolation Polynomial:\n";

for (int i = intrFunc.Length - 1; i > 0; i--)

{

lab.Text += String.Format("{0:F5}x^{1} + ", intrFunc[i], i);

}

lab.Text += String.Format("{0:F5}\n", intrFunc[0]);

lab.Text += "Derivative of Polynomial:\n";

for (int i = difPolinom.Length - 1; i > 0; i--)

{

lab.Text += String.Format("{0:F5}x^{1} + ", difPolinom[i], i);

}

lab.Text += String.Format("{0:F5}\n", difPolinom[0]);

}

}

}

Модуль MathBase.cs:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Kursavik_sem_3

{

class MathBase

{

//метод копирует матрицу MatIn в матрицу MatOut

static void copy(decimal[,] MatIn, decimal[,] MatOut)

{

int a = MatIn.GetLength(0);

int b = MatIn.GetLength(1);

for (int i = 0; i < a; i++)

for (int j = 0; j < b; j++) MatOut[i, j] = MatIn[i, j];

}

//метод обменивает указанные строки матрицы

static void swap(decimal[,] matrix, int a, int b)

{

int len = matrix.GetLength(1);

if (a != b)

for (int i = 0; i < len; i++)

{

decimal buf;

buf = matrix[a, i];

matrix[a, i] = matrix[b, i];

matrix[b, i] = buf;

}

}

//метод делает матрицу диаганальной

static void GetDiaganal(decimal[,] matrix)

{

int a = matrix.GetLength(0);

int b = matrix.GetLength(1);

for (int i = 0; i < a - 1; i++)

{

int max = i, sw = i;

decimal maxVol = Math.Abs(matrix[i, i]);

//находим максимальный элемент в столбце

for (int j = i; j < a; j++)

{

if (Math.Abs(matrix[j, i]) > maxVol)

{

maxVol = Math.Abs(matrix[j, i]);

max = j;

}

}

//меняем строки местами

swap(matrix,max,sw);

decimal kof;

//вычитаем строки.

for (int j = i + 1; j < a; j++)

{

kof = matrix[j, i] / matrix[i, i];

for (int k = i; k < b; k++)

{

matrix[j, k] -= kof * matrix[i, k];

}

}

}

}

//метод решает СЛАУ

public static void GetSolve(decimal[,] inMat, decimal[] Solve)

{

decimal[,] buffer = new decimal[inMat.GetLength(0),inMat.GetLength(1)];

copy(inMat, buffer);

GetDiaganal(buffer);

int a = inMat.GetLength(0);

int b = inMat.GetLength(1);

for (int i = a - 1; i >= 0; i--)

{

decimal resul = buffer[i, b - 1];

for (int j = b - 2; j > i; j--) resul -= buffer[i, j] * Solve[j];

Solve[i] = resul / buffer[i, i];

}

}

//метод берет производную от полинома

public static void GetDifferPolinom(decimal[] inMat, decimal[] outMat)

{

for (int i = 0; i < inMat.Length - 1; i++)

outMat[i] = inMat[i + 1] * (i + 1);

}

//метод считает значение полинома

public static decimal Fx(decimal[] polinom, decimal x)

{

decimal ans = 0;

for (int i = 0; i < polinom.Length; i++)

{

ans +=polinom[i] * (decimal)(Math.Pow((double)x,(double)i));

}

return ans;

}

}

}

Приложение Б

Руководство пользователя

Описание программы:

Данная программа предназначена для нахождения производной функции, заданной таблично.

Программа может рассчитывать производную двумя способами: с помощью разностных формул и с помощью интерполяционного многочлена Лагранжа.

Системные требования:

Процессор: 800 МГц и выше.

Операционная система: Windows 7 и выше.

Дополнительное ПО:.NET Framework 4.

Стартовое окно.

Во время запуска программы вы увидите следующее окно, показанное на рисунке Б.1:

Рисунок Б.1 - Стартовое окно программы

Данное окно содержит все необходимое для нахождения значения производной в нужной точке.

В данном окне можно:

1) Задать множество точек функции.

2) Задать точку, в которой нужно найти производную.

3) Задать метод решения задачи.

4) Ознакомиться с результатами решения в текстовом и графическом видах.

Добавление точки.

Для того, чтобы добавить точку в множеству точек функции необходимо в поля "X" и "Y" (на рисунке Б.2 обозначены 1) ввести необходимые данные. После этого нажать кнопку "Add" (на рисунке обозначена 2) или клавишу Enter. Если в поле будут введены не корректные данные, будет показано соответствующее предупреждение, а данные не будут занесены в таблицу.

Рисунок Б.2 - Добавление точки функции

Удаление точки

Если вы убрать какие-то точки из расчета, то необходимо выбрать соответствующие точки в списке "Point List" (на рисунке обозначен 1). После этого необходимо нажать клавишу "Delete" (на рисунке Б.3 обозначена 2). После этого указанные точки будут удалены. Если не выбрана ни одна точка, то при попытке нажатия клавишу "Delete" будет выведено предупреждение.

Рисунок Б.3 - Удаление точки из списка

Выбор метода

Для того, чтобы выбрать интересующий вас метод решения, необходимо на нажать на выпадающий список с заголовком "Selected method" (выделен на рисунке Б.4) и выбрать в списке один из двух методов.

Difference derivation - использует разностные формулы вычисления производной.

Polynomial Interpolation - использует интерполяционный многочлен Лагранжа.

Рисунок Б.4 - Выбор метода дифференцирования

Выбор точки для дифференцирования

Для того, чтобы произвести расчет производной, нужно указать точку, в которой будет производиться расчет.

В поле ввода с заголовком "Point for differentiation" (выделено на рисунке Б.5) нужно ввести точку. Если будет введено некорректное значение, при попытке рассчитать производную, будет показано предупреждающее сообщение, а расчет не будет произведен. Однако, если точка не будет удовлетворять условиям метода, расчет будет произведен, но вместо результатов будет выведено: "Нет решения".

Для того, чтобы начать расчет, нужно нажать кнопку "Find derivative" или клавишу Enter.

Рисунок Б.5 - Выбор точки дифференцирования

Результаты работы

После завершения расчетов по поле, выделенном на рисунке Б.6 будут отображаться результаты, а также некоторая информация о решении задачи.

Также в данном поле может быть информация о невозможности решить задачу данным методом, или информация об ошибке, когда одному аргументу функции соответствует два значения функции.

Рисунок Б.6 - Результаты расчета

Окно настройки графика

Для того, чтобы открыть окно(рисунок Б.8) управления графиком, в меню необходимо перейти Setting->Grafic (рисуонк Б.7).

Рисунок Б.7 - Включение окна настройки графика

В окне настройки графика возможно:

1) Задать смещение графика по осям.

2) Задать масштаб графика.

Рисунок Б.8 - Настройка графика

Настройки графика.

Для настройки смещения графика по осям, необходим в поля (выделены 1 на рисунке Б.9) прописать необходимое смещения.

Для масштабирования графика необходимо двигать ползунок (выделен 2 на рисунке Б.9).

Рисунок Б.9 - Выбор параметров графика

Размещено на Allbest.ru


Подобные документы

  • Вычисление производной по ее определению, с помощью конечных разностей и на основе первой интерполяционной формулы Ньютона. Интерполяционные многочлены Лагранжа и их применение в численном дифференцировании. Метод Рунге-Кутта (четвертого порядка).

    реферат [71,6 K], добавлен 06.03.2011

  • Геометрический смысл производной. Анализ связи между непрерывностью и дифференцируемостью функции. Производные основных элементарных функций. Правила дифференцирования. Нахождение производной неявно заданной функции. Логарифмическое дифференцирование.

    презентация [282,0 K], добавлен 14.11.2014

  • Методы хорд и итераций, правило Ньютона. Интерполяционные формулы Лагранжа, Ньютона и Эрмита. Точечное квадратичное аппроксимирование функции. Численное дифференцирование и интегрирование. Численное решение обыкновенных дифференциальных уравнений.

    курс лекций [871,5 K], добавлен 11.02.2012

  • Производные основных элементарных функций. Логарифмическое дифференцирование. Показательно-степенная функция и ее дифференцирование. Производная обратных функций. Связь между дифференциалом и производной. Теорема об инвариантности дифференциала.

    лекция [191,4 K], добавлен 05.03.2009

  • Обзор таблицы производных элементарных функций. Понятие промежуточного аргумента. Правила дифференцирования сложных функций. Способ изображения траектории точки в виде изменения ее проекций по осям. Дифференцирование параметрически заданной функции.

    контрольная работа [238,1 K], добавлен 11.08.2009

  • Непрерывная и точечная аппроксимация. Интерполяционные полиномы Лагранжа и Ньютона. Погрешность глобальной интерполяции, квадратичная зависимость. Метод наименьших квадратов. Подбор эмпирических формул. Кусочно-постоянная и кусочно-линейная интерполяции.

    курсовая работа [434,5 K], добавлен 14.03.2014

  • Нормированное пространство – одно из основных понятий функционального анализа, дифференцирование. Формула конечных приращений; связь между слабой и сильной дифференцируемостью. Абстрактные функции; интеграл; производные и дифференциалы высших порядков.

    курсовая работа [125,9 K], добавлен 24.01.2011

  • Компьютерная программа, реализующая полиномиальную аппроксимацию подынтегральной функции для вычисления точного значения интеграла. Язык программирования Visual Basic. Описание средств программного интерфейса. Интерактивная форма для ввода данных.

    курсовая работа [476,5 K], добавлен 27.04.2011

  • Особенности решения линейных и нелинейных уравнений. Характеристика и практическое применение и различных методов при решении уравнений. Сущность многочлена Лагранжа и обратного интерполирования. Сравнение численного дифференцирования и интегрирования.

    курсовая работа [799,6 K], добавлен 20.01.2010

  • Определение предела последовательности. Понятие производной и правила дифференцирования. Теоремы Роля, Лангража, правило Лапиталя. Исследования графиков функций. Таблица неопределенных и вычисление определенных интегралов. Функции нескольких переменных.

    презентация [917,8 K], добавлен 17.03.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.