Методы аппроксимаций функций

Тип работы:
Курсовая
Предмет:
Физико-математические науки


Узнать стоимость

Детальная информация о работе

Выдержка из работы

Введение

Из курса математики известны 3 способа задания функциональных зависимостей: 1) аналитический 2) графический 3) табличный. Табличный способ обычно возникает в результате эксперимента. Недостаток табличного задания функции заключается в том, что найдутся значения переменных которые неопределенны таблицей. Для отыскания таких значений определяют приближающуюся к заданной функцию, называемой аппроксимирующей, а действие замены аппроксимацией. Аппроксимация заключается в том что, используя имеющуюся информацию по f (x) можно рассмотреть другую функцию близкую в некотором смысле к f (x), позволяющую выполнить над ней соответствующие операции и получить оценку погрешность такой замены.

1. Постановка задачи

В ходе физического эксперимента получены следующие данные с интервалом 1с (первое наблюдение выполнено в момент t=1,0):

t=1. 9

t=10. 18

t=19. 25

5,0291

6,5099

5,3666

4,1272

4,2948

6,1261

12,5140

10,0502

9,1614

7,5677

7,2920

10,0357

11,0708

13,4045

12,8415

11,9666

11,0765

11,7774

14,5701

17,0440

17,0398

15,9069

15,4850

15,5112

17,6572

Подберите аппроксимирующий полином методом наименьших квадратов. Аппроксимируйте данные моделью:

Проанализируйте результаты.

2. Теоретические предпосылки

2. 1 Аппроксимация функций методом наименьших квадратов

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

наименьший квадрат алгоритм mathcad

(2. 32)

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

Параметры подбирают так, чтобы выполнялся критерий.

Чаще всего используются 2−3 параметрические функции, следующих семейств:

,, , ,

дробно-линейная,

логарифмическая,

обратно-пропорциональная,

дробно-рациональная,

где a, b, c — параметры

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

(2. 33)

где — - некоторые базисные функции, то такая аппроксимация называется линейной.

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

Применение степенных базисных функций

Очень часто для приближения по методу наименьших квадратов используются алгебраические многочлены степени mn, т. е. k=0. . m. В этом случае обобщенный многочлен (2. 33) имеет вид

, а коэффициенты, исходя из критерия (2. 32), ищутся из системы следующего вида:

(k= 0,1,…, m).

(2. 34)

или в развернутом виде:

(2. 35)

В случае многочлена первой степени P1(x)=c0+c1x, эта система принимает вид

(2. 36)

Для многочлена второй степени P2(x)=c0+c1x+c2x2:

(2. 37)

3. Описание программного средства

3. 1 Спецификация переменных, процедур и функций

Void XY_print () — Функция очищает экран и рисует координатные оси.

double P (double *vek, int m, double xx) — функция для вычисления значения многочлена.

double Q (double *a, int m) — функция, возвращающая среднеквадратическое отклонение со входным параметром — вектором значений *a.

void draw (double *X, int col, int count, double q) — функция, выводящая график функции аппроксимированной по методу наименьших квадратов полиномом; входные данные — вектор значений *X, цвет col, целое число count и значение среднеквадратического отклонения q.

double lsolve (double **array, double *vek, int nn, double *X) — функция, решающая СЛАУ методом Гаусса.

double mnk (double m, int color) — функция, аппроксимирующая функцию y=f (x) методом наименьших квадратов

_mnk () — Функция аппроксимирует данные моделью: y (t)=x1+x2*t+x3*sin (t) по методу наименьших квадратов.

void menu () — функция вывода меню на экран.

int main () — главная функция.

3. 2 Схемы алгоритмов

double mnk (double m, int color)

/

/

/

/

double _mnk ()

/

/

/

/

4. Расчеты в системы Mathcad

4.1 Контрольный пример работы

Рисунок 1 — Метод наименьших квадратов

Рисунок 2 — Аппроксимация моделью:, по методу наименьших квадратов.

4.2 График в среде в программирования

Рисунок 3 — Метод наименьших квадратов

Рисунок 4 — Метод наименьших квадратов моделью

Заключение

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

Список использованных источников

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

2. Лапчик М. П. Численные методы: Учебное пособие для вузов / Рагулина М. И., Хеннер Е. К.; под редакцией Лапчика М. П.: Издательский центр «Академия», 2004. - 384 с.

3. Бахвалов Н. С., Жидков Н. П., Кобельков Г. М. — Численные методы (2 изд.).

4. Тарасов В. Н. Численные методы, теория, алгоритмы, программы: Учебное пособие для вузов / Бахарева Н. Ф; под редакцией Тарасова В. П.: Издательский центр Оренбург: ИПК ОГУ, 2003. — 100 с.

Приложение А

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

#include < iostream. h>

#include < graphics. h>

#include < conio. h>

#include < stdio. h>

#include < string. h>

#include < math. h>

#include < stdlib. h>

void init_graph () {

int gdriver = DETECT, gmode, errorcode;

initgraph (& gdriver, & gmode, ««);

errorcode = graphresult ();

if (errorcode≠ grOk) {

printf («Graphics error: %sn», grapherrormsg (errorcode));

printf («Press any key to halt: «);

getch ();

exit (1);

}

}

const n=25;

double x[n]={1. 0,2. 0,3. 0,4. 0,5. 0,6. 0,7. 0,8. 0,9. 0,10. 0,11. 0,12. 0,13. 0,14. 0,

15. 0,16. 0,17. 0,18. 0,19. 0,20. 0,21. 0,22. 0,23. 0,24. 0,25. 0};

double y[n]={5. 0291,6. 5099,5. 3666,4. 1272,4. 2948,6. 1261,12. 5140,10. 0502,9. 1614,7. 5677,7. 2920,10. 0357,11. 0708,

13. 4045,12. 8415,11. 9666,11. 0765,11. 7774,14. 5701,17. 0440,17. 0398,15. 9069,15. 4850,15. 5112,17. 6572};

int menu_output ()

{

cout< <" г============================================================================nr";

cout< <" ¦ 0. Approx. model (y (t)=x1+x2*t+x3*sin (t)) ¦nr";

cout< <" ¦ 1. Real grafik ¦nr";

cout< <" ¦ 2. Grafik po MNK ¦nr";

cout< <" ¦ 3. Ochistit' ¦nr";

cout< <" ¦============================================================================¦nr";

cout< <" ¦ ESC — Exit ¦nr";

cout< <" L============================================================================-nr";

return 0;

}

void XY_print () { // Вырисовка осей

setlinestyle (0,0,1);

setbkcolor (0);

setfillstyle (1,0);

setcolor (WHITE);

bar (0,0,680,459);

line (20,380,320,380);

line (160,400,160,180);

line (320,380,310,375);

line (320,380,310,385);

line (160,180,155,190);

line (160,180,165,190);

outtextxy (145,180, «Y»);

outtextxy (320,390, «X»);

outtextxy (145,390, «0»);

}

void p_pixel (double x, double y, int col) {

putpixel (x+160, — y+380, col);

}

double P (double *vek, int m, double xx) { // Значение многочлена

double tem=0;

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

if (! i) tem+=vek[i];

else tem+=vek[i]*pow (xx, i);

return tem;

}

double Q (double *a, int m) { // значение среднеквадратичного отклонение многочлена P

double temp=0;

for (int i=0; i< n; i++) temp+=pow ((P (a, m, x[i]) — y[i]), 2);

temp=temp/n;

temp=sqrt (temp);

temp=ddd [m-1];

return temp;

}

void draw (double *X, int col, int count, double q) { // рисует график по MNK

setfillstyle (1,0);

cout< <"Otklonenie: «< <q<<endl;

double y, temp;

for (double xx=1; xx< =25; xx+=0. 001) {

y=0;

for (int t=0; t< count; t++)

if (! t) y+=X[t];

else y+=X[t]*pow (xx, t);

p_pixel (xx*6, y*6, col);

}

}

// -Решение СЛАУ методом Гауса-

double lsolve (double **array, double *vek, int nn, double *X) {

int *IOR=new int[nn];

int i, l, k, M, j, p;

double AKK, AMAIN, delitel;

for (k=0; k< nn; k++) IOR[k]=k;

// -Нахождение индекса-

for (k=0; k< nn; k++) {

AKK=0;

for (i=k; i< nn; i++) {

l=IOR[i];

if (fabs (array[l] [k])< AKK) continue;

M=l; p=i; AKK=fabs (array[l] [k]);

}

// -Меняем места-

AMAIN=array[M] [k];

if (k≠p) {IOR[p]=IOR[k]; IOR[k]=M; };

// -Прямой ход-

for (j=k; j< nn; j++) array[M] [j]=array[M] [j]/AMAIN;

vek[M]=vek[M]/AMAIN;

for (i=k+1; i< nn; i++) {

l=IOR[i];

delitel=array[l] [k];

for (j=k; j< nn; j++) array[l] [j]=array[l] [j] - delitel*array[M] [j];

vek[l]=vek[l] - delitel*vek[M];

}

}

// -Обратный ход-

double sum;

for (k=nn-1; k> =0; k-) {

l=IOR[k];

sum=0;

for (j=k+1; j< nn; j++) sum=sum+array[l] [j]*X[j];

X[k]=vek[l] - sum;

}

delete[] IOR;

return *X;

}

double mnk (double m, int color) { // Наименьших квадратов

double **A=new double *[n];

for (int i=0; i< n; i++) A[i]=new double [m];

double *b=new double [m];

double s=0;

for (int j=0; j< m; j++) {

s=0;

for (int i=0; i< n; i++) {

if (! j) s+=y[i];

else s+=y[i]*pow (x[i], j);

}

b[j]=s;

for (int k=0; k< m; k++) {

s=0;

for (i=0; i< n; i++)

if (! (k+j)) s+=1;

else s+=pow (x[i], k+j);

A[j] [k]=s;

}

}

double *X=new double [m];

*X=lsolve (A, b, m, X); //if (m==25) {X=a25; }

draw (X, color, m, Q (X, 25));

delete[] A;

delete[] X;

delete[] b;

return 0;

}

double _mnk () { // Аппроксимация данных моделью (y (t)=x1+x2*t+x3*sin (t) по mnk

int m=13;

double *X=new double[m];

double **A=new double *[n];

for (int i=0; i< n; i++) A[i]=new double [m];

double *b=new double [m];

double s=0;

for (int j=0; j< m; j++) {

s=0;

for (int i=0; i< n; i++) {

if (! j) s+=y[i];

else s+=y[i]*pow (x[i], j);

}

b[j]=s;

for (int k=0; k< m; k++) {

s=0;

for (i=0; i< n; i++)

if (! (k+j)) s+=1;

else s+=pow (x[i], k+j);

A[j] [k]=s;

}

}

*X=lsolve (A, b, m, X);

clrscr ();

XY_print ();

menu_output ();

double **matr=new double*[3];

for (i=0; i< 3; i++) matr[i]=new double[3];

double *bb=new double[3];

double *cc=new double[3];

matr[0] [0]=1;

for (i=0; i< n; i++) matr[0] [1]+=x[i];

for (i=0; i< n; i++) matr[0] [2]+=sin (x[i]);

for (i=0; i< n; i++) b[0]+=p (A, 15, i);

for (i=0; i< n; i++) matr[1] [0]+=x[i];

for (i=0; i< n; i++) matr[1] [1]+=x[i]*x[i];

for (i=0; i< n; i++) matr[1] [2]+=x[i]*sin (x[i]);

for (i=0; i< n; i++) bb[1]+=x[i]*p (A, 15, i);

for (i=0; i< n; i++) matr[2] [0]+=sin (x[i]);

for (i=0; i< n; i++) matr[2] [1]+=x[i]*sin (x[i]);

for (i=0; i< n; i++) matr[2] [2]+=sin (x[i])*sin (x[i]);

for (i=0; i< n; i++) bb[2]+=p (A, 15, i)*sin (x[i]);

*cc=lsolve (matr, bb, 3, cc);

cout< < «x1="< <cc[0]<<endl;

cout< < «x2="< <cc[1]<<endl;

cout< < «x3="< <cc[2]<<endl;

double yy, yy1;

yy1=0;

for (double xx=1; xx< =25; xx+=1) {

yy=cc[0]+cc[1]*xx+cc[2]*sin (xx);

line (xx*6+160, — yy*6+380, (xx-1)*6+160, — yy1*6+380);

yy1=yy;

p_pixel (xx*6, yy*6,2);

}

delete[] A;

delete[] X;

delete[] b;

return 0;

}

void real_graph () {

setcolor (4);

setfillstyle (1,0);

setlinestyle (0,0,3);

setcolor (RED);

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

circle (x[i]*6+160, — y[i]*6+380,1);

}

int main () {

char ch;

clrscr ();

init_graph ();

XY_print ();

menu_output ();

do

{

ch=getch ();

switch (ch)

{

case '0':

_mnk ();

break;

case '1':

real_graph ();

break;

case '2':

mnk (25,2);

break;

case '3':

clrscr ();

XY_print ();

menu_output ();

break;

default:

break;

}

if (ch==27)

{

exit (0);

}

} while (ch≠27);

return 0;

}

ПоказатьСвернуть
Заполнить форму текущей работой