Информатика: Функции — различия между версиями
Строка 2037: | Строка 2037: | ||
'''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется. | '''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется. | ||
+ | |||
Скачать программу можно по [http://mech.spbstu.ru/File:Untitled1.rar ссылке] | Скачать программу можно по [http://mech.spbstu.ru/File:Untitled1.rar ссылке] | ||
<div class="mw-collapsible mw-collapsed" style="width:100%" > | <div class="mw-collapsible mw-collapsed" style="width:100%" > | ||
+ | Метод наименьших квадратов | ||
+ | задача состоит в том, чтобы минимизировать выражение: | ||
+ | 1: http://mech.spbstu.ru/images/b/b0/003.png | ||
+ | Доказано, что минимум достигается при: | ||
+ | 2: http://mech.spbstu.ru/images/2/20/005.png | ||
+ | записываем пункт 2 в нашу программу, находим коэффициенты и находим значение линейной функции y=ax+b, по интерполированным значениям x. | ||
+ | |||
+ | |||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
<syntaxhighlight lang="cpp" line start="1" enclose="div"> | <syntaxhighlight lang="cpp" line start="1" enclose="div"> |
Версия 19:48, 17 января 2016
Описание программы: программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.
Пояснения к алгоритму:
- Прочитанные из файла функции нужно отсортировать.
- Найти совместную область определения, то есть, найти множество пересечения областей определения функций, над которыми совершается операция.
- Создать третью функцию, со следующими свойствами : область определения состоит только из точек, принадлежащих совместной области определения, каждая точка области значений является результатом нужной операции над точкой области значений одной из функций и, либо интерполированной точкой по другой функции, либо, если есть возможность, точным значением из ее области значений.
Скачать можно тут.
1 #include <iostream>
2 #include <math.h>
3 #include <cstring>
4 #include <cmath>
5 #include <malloc.h>
6 #include <fstream>
7
8 using namespace std;
9
10 double base(double x) //базовая функция ( если задавать через шаг и начальный х
11 {
12 return x;
13 }
14
15 struct ap //две одинаковые структуры это нехорошо,коненчо,но зато наглядно...
16 {
17 double k,b;
18 };
19
20 struct fun //один столбик в таблице функции
21 {
22 double x,y;
23 };
24
25 struct sf //структура нужная, для возражеия значений из функции "prepare" класса F
26 {
27 int i1,i2,e1,e2;
28 double glength, gfirstx, glastx;
29 };
30
31 double intr(double x1,double x2,double x,double y1,double y2) // линенейная интерполяция
32 {
33 return ( ((x-x1)/(x2-x1)) * (y2-y1) + y1 );
34 }
35
36 ap aproks(fun b [],int n) //линейная аппроксимация
37 {
38 ap r;
39 double xy = 0,x = 0,y = 0,sqx = 0,xsq = 0;
40 for (int i = 0; i < n; i++) //вычисление коэффицентов
41 {
42 xy += b[i].x*b[i].y;
43 x += b[i].x;
44 y += b[i].y;
45 sqx += b[i].x*b[i].x;
46 xsq += b[i].x;
47 }
48 xsq *= xsq;
49
50 r.k = (n*xy - x*y)/(n*sqx - xsq); //использование формул
51 r.b = (y - r.k*x)/n;
52 return r;
53 }
54
55 class F
56 {
57 private:
58 int length;
59 double firstx, step, lastx;
60 fun *a;
61 public:
62 F(){}
63 F(int l,double f,double s) //конструктор, создающий фунцию по длине,первоиу элементу,шагу по х, y вычисляется по базовой функции
64 {
65 if (l >= 0)
66 a = new fun [l];
67 firstx = f;
68 length = l;
69 step = s;
70 lastx = firstx+(length - 1)*step;
71
72
73 for (int i = 0;i < length; i ++)
74 {
75 a[i].y = base(firstx + i*step);
76 a[i].x = firstx + i*step;
77 }
78
79 }
80
81 F (fun b[],int l) //конструктор для создания фунции с уже известными областями определния и значений
82 {
83 length = l;
84 a = new fun [l];
85 for (int i = 0; i < l;i++)
86 a[i] = b[i];
87
88 for (int i = 0; i < l;i++)
89 for (int j = 0; j < (l - 1); j++)
90 if (a[j].x > a[j + 1].x)
91 {
92 fun tmp = a[j];
93 a[j] = a[j + 1];
94 a[j + 1] = a[j];
95 }
96
97 firstx = a[0].x;
98 lastx = a[length - 1].x;
99 }
100
101 void addpar (double k, double b, int l, fun z[] ) //позволяет создать и заполнить переданным массивом поле объекта класса
102 {
103 a = new fun [l];
104 for (int i = 0; i < l; i++)
105 {
106 a[i].y = k*z[i].x + b;
107 a[i].x = z[i].x;
108 }
109 length = l;
110 }
111
112 double getelx(int i) //возращает значение из поля "х" iого элемента
113 {
114 return a[i].x;
115 }
116
117
118 double getely(int i) //возращает значение из поля "х" iого элемента
119 {
120 return a[i].y;
121 }
122
123 int getlength() //возращает размер области определения функции(в точках)
124 {
125 return length;
126 }
127
128 void FOut() //выводит функцию на экран
129 {
130 cout << " x y" << endl;
131 for (int i = 0;i < length; i ++)
132 cout << " " << a[i].x << " " << a[i].y << endl;
133 cout << endl;
134 }
135
136
137 int pfind(double x)const //возращает либо номер элемента,идущщий перед элементом, большим,чем х; в случае нахождения равного, возращает число, противоположное номеру следующего элемента(иначе может вернуться нуль,а нуль знака не имееет)
138 {
139 for (int i = 0; i < length-1; i++ )
140 {
141 if (((a[i].x < x) && (a[i + 1].x > x)))
142 return (i + 1);
143 else
144 // чтобы иметь возможность проанализировать полученное значение функции,мы должны понимать, было найденно равное или промежуточное значение. "флагом" равных значений является знак минус,но так у нуля нет знака,то приходиться все сдвигать на 1
145 if (a[i].x == x)
146 return -(i + 1);
147 else
148 if (a[i + 1].x == x)
149 return -(i + 2);
150 }
151 // cerr << "fail!!" << endl;
152 return -1;
153 }
154
155 sf prepare(F &x)const //"подготовка" функций к бинарной операции (нахождение совместной области определения
156 {
157 sf r;
158 if (a[0].x > x.a[0].x)
159 {
160 r.gfirstx = a[0].x;
161 r.i1 = 0;
162 r.i1 = 0;
163 double k = x.pfind(a[0].x);
164 if (k < 0)
165 r.i2 = -k - 1;
166 else
167 r.i2 = (k - 1) + 1;
168 }
169 else
170 {
171 r.gfirstx = x.a[0].x;
172 double k = pfind(x.a[0].x);
173 if (k < 0)
174 r.i1 = -k - 1;
175 else
176 r.i1 = (k - 1) + 1;
177 r.i2 = 0;
178 }
179
180 if (a[length - 1].x < x.a[x.length - 1].x)
181 {
182 r.glastx = a[length - 1].x;
183 r.e1 = length - 1;
184 double k = x.pfind(r.glastx);
185 if (k < 0)
186 r.e2 = -k - 1;
187 else
188 r.e2 = (k - 1) - 1;
189 }
190 else
191 {
192 r.glastx = x.a[x.length - 1].x;
193 double k = pfind(r.glastx);
194 if (k < 0)
195 r.e1 = -k - 1;
196 else
197 r.e1 = (k - 1) + 1;
198 r.e2 = x.length - 1;
199 }
200 r.glength = length + x.length - r.i1 - (length - (r.e1 + 1)) - r.i2 - (x.length - (r.e2 + 1));
201
202 return r;
203 }
204
205 void ad (fun b[],int l) //присвоить массиву объекта класса F значения массива b
206 {
207 length = l;
208 a = new fun [l];
209 for (int i = 0; i < l;i++)
210 a[i] = b[i];
211 firstx = a[0].x;
212 lastx = a[length - 1].x;
213 }
214
215 fun *geta() //получения указателя на начало массива в поле класса
216 {
217 return a;
218 }
219
220 F operator +(F &x) const //сложение двух функций
221 {
222 int i1, e1, i2, e2, kk = 0;
223 double gfirstx, glastx, glength;
224
225 if (((x.lastx < firstx) && (x.firstx < firstx)) || ((lastx < x.firstx) && (firstx < x.firstx)))
226 {
227 cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
228 F fl(-1,0,0);
229 return fl;
230 }
231 sf r = prepare(x);
232 F tmp(r.glength,r.gfirstx,r.glastx);
233 for (int i = 0; i <= (r.e1 - r.i1); i++)
234 {
235 tmp.a[i].x = a[i + r.i1].x; //поправка,введенная таким образом,чтобы номер,с которого начинается отсчет был первым в новой области определения
236 int ii = x.pfind(tmp.a[i].x);
237 if (ii < 0)
238 tmp.a[i].y = x.a[-ii - 1].y + a[i + r.i1].y;
239 else
240 tmp.a[i].y = intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y) + a[i + r.i1].y;
241 }
242 for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
243 {
244 int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
245 if (ii >= 0)
246 {
247 tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
248 tmp.a[i - kk].y = intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y) + x.a[i - (r.e1 - r.i1 + 1) + r.i2].y;
249 }
250 else
251 {
252 kk++;
253 glength --;
254 tmp.length --;
255 }
256 }
257
258 for (int i = 0; i < glength; i++)
259 for (int j = 0; j < glength - 1; j++)
260 if (tmp.a[j].x > tmp.a[j + 1].x)
261 {
262 fun t = tmp.a[j];
263 tmp.a[j] = tmp.a[j + 1];
264 tmp.a[j + 1] = t;
265 }
266
267 return tmp;
268 }
269
270 F operator *(F & x) const //умножение двух функций
271 {
272 int i1, e1, i2, e2, kk = 0;
273 double gfirstx, glastx, glength;
274
275 if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
276 {
277 cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
278 F fl(-1,0,0);
279 return fl;
280 }
281
282 sf r = prepare(x);
283 F tmp(r.glength,r.gfirstx,r.glastx);
284
285 for (int i = 0; i <= (r.e1 - r.i1); i++)
286 {
287 tmp.a[i].x = a[i + r.i1].x;
288 int ii = x.pfind(tmp.a[i].x);
289 if (ii < 0)
290 tmp.a[i].y = x.a[-ii - 1].y * a[i + r.i1].y;
291 else
292 tmp.a[i].y = intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y) * a[i + r.i1].y;
293 }
294 for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
295 {
296 int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
297 if (ii >= 0)
298 {
299 tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
300 tmp.a[i - kk].y = intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y) * x.a[i - (r.e1 - r.i1 + 1) + r.i2].y;
301 }
302 else
303 {
304 kk++;
305 glength --;
306 tmp.length --;
307 }
308 }
309
310 for (int i = 0; i < glength; i++)
311 for (int j = 0; j < glength - 1; j++)
312 if (tmp.a[j].x > tmp.a[j + 1].x)
313 {
314 fun t = tmp.a[j];
315 tmp.a[j] = tmp.a[j + 1];
316 tmp.a[j + 1] = t;
317 }
318
319 return tmp;
320 }
321
322 F operator ^(F & x) const //возведение функции слева от оператора в степень функции справа от оператора
323 {
324 int i1, e1, i2, e2, kk = 0;
325 double gfirstx, glastx, glength;
326
327 if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
328 {
329 cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
330 F fl(-1,0,0);
331 return fl;
332 }
333
334 sf r = prepare(x);
335 F tmp(r.glength,r.gfirstx,r.glastx);
336
337 for (int i = 0; i <= (r.e1 - r.i1); i++)
338 {
339 tmp.a[i].x = a[i + r.i1].x;
340 int ii = x.pfind(tmp.a[i].x);
341 if (ii < 0)
342 tmp.a[i].y = pow(x.a[-ii - 1].y, a[i + r.i1].y);
343 else
344 tmp.a[i].y = pow(intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y), a[i + r.i1].y);
345 }
346 for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
347 {
348 int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
349 if (ii >= 0)
350 {
351 tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
352 tmp.a[i - kk].y = pow(intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y), x.a[i - (r.e1 - r.i1 + 1) + r.i2].y);
353 }
354 else
355 {
356 kk++;
357 glength --;
358 tmp.length --;
359 }
360 }
361
362 for (int i = 0; i < glength; i++)
363 for (int j = 0; j < glength - 1; j++)
364 if (tmp.a[j].x > tmp.a[j + 1].x)
365 {
366 fun t = tmp.a[j];
367 tmp.a[j] = tmp.a[j + 1];
368 tmp.a[j + 1] = t;
369 }
370
371 return tmp;
372 }
373 };
374
375 int main()
376 {
377 /*
378 F f1(5,-2,1.5);
379 F f2(30,-10,0.5);
380 F f3, f4;
381 f1.FOut();
382 f2.FOut();
383 f3 = f1 + f2;
384 f3.FOut();
385 f4 = f1 * f2;
386 f4.FOut();
387 cout << " ________" << endl;
388 */
389 char vc, s[255], ce;
390 ifstream infile;
391 int n;
392 fun *a;
393 F f5,f6,f7,f8,f9;
394
395 while(true)
396 {
397 start :
398 system("cls");
399 cout << "1 - Vvesti 1uu func" << endl;
400 cout << "2 - Vvesti 2uu func" << endl;
401 cout << "3 - Sloshit'" << endl;
402 cout << "4 - Umnozhit'" << endl;
403 cout << "5 - Vozvesti v stepen'" << endl;
404 cout << "6 - Aproximirovat'" << endl;
405 cout << "7 - Zapics' v file func" << endl;
406 cout << "8 - Zapics' v file aprok fun" << endl;
407 cout << "0 - Vihod" << endl;
408 cin >> vc;
409 switch (vc)
410 {
411 case '0':
412 return 0 ;
413 case '1':
414 {
415 system("cls");
416 strcpy(s,"");
417 delete []a;
418 a = NULL;
419 cout << "Vvedite imya fila" << endl;
420 cin >> s;
421 strcat(s, ".txt");
422 infile.open(s);
423 infile >> n;
424 a = new fun [n];
425 for(int i = 0; i < n; i ++)
426 infile >> a[i].x >> a[i].y;
427 f5.ad(a,n);
428 f5.FOut();
429 infile.close();
430 cout << "Nazhmite \"b\" chotibi viti" << endl;
431 cin >> ce;
432 while (true)
433 if (ce == 'b')
434 goto start;
435 }
436 case '2':
437 {
438 system("cls");
439 strcpy(s,"");
440 delete []a;
441 a = NULL;
442 cout << "Vvedite imya fila" << endl;
443 cin >> s;
444 strcat(s, ".txt");
445 infile.open(s);
446 infile >> n;
447 a = new fun[n];
448 for(int i = 0; i < n; i ++)
449 infile >> a[i].x >> a[i].y;
450 f6.ad(a,n);
451 f6.FOut();
452 infile.close();
453 cout << "Nazhmite \"b\" chotibi viti" << endl;
454 cin >> ce;
455 while (true)
456 if (ce == 'b')
457 goto start;
458 }
459 case '3':
460 system("cls");
461 f5.FOut();
462 f6.FOut();
463 f7 = f5 + f6;
464 f7.FOut();
465 cout << "Nazhmite \"b\" chotibi viti" << endl;
466 cin >> ce;
467 while (true)
468 if (ce == 'b')
469 goto start;
470 case '4':
471 system("cls");
472 f5.FOut();
473 f6.FOut();
474 f7 = f5 * f6;
475 f7.FOut();
476 cout << "Nazhmite \"b\" chotibi viti" << endl;
477 cin >> ce;
478 while (true)
479 if (ce == 'b')
480 goto start;
481 case '5':
482 system("cls");
483 f5.FOut();
484 f6.FOut();
485 f7 = f5 ^ f6;
486 f7 = f5 ^ f6;
487 f7.FOut();
488 cout << "Nazhmite \"b\" chotibi viti" << endl;
489 cin >> ce;
490 while (true)
491 if (ce == 'b')
492 goto start;
493 case '6':
494 {
495 system("cls");
496 ap tmp = aproks(f7.geta(), f7.getlength());
497 f8.addpar(tmp.k, tmp.b, f7.getlength(), f7.geta());
498 f8.FOut();
499 cout << "Nazhmite \"b\" chotibi viti" << endl;
500 cin >> ce;
501 while (true)
502 if (ce == 'b')
503 goto start;
504 }
505 case '7':
506 {
507 system("cls");
508 strcpy(s,"");
509 cout << "Vvedite imya fila" << endl;
510 cin >> s;
511 strcat(s, ".txt");
512 ofstream outfile(s);
513 outfile << "x y" << endl;
514 for (int i = 0; i < f7.getlength(); i ++)
515 outfile << f7.getelx(i) << " " << f7.getely(i) << endl;
516
517 cout << "done" << endl;
518 cout << "Nazhmite \"b\" chotibi viti" << endl;
519 cin >> ce;
520 while (true)
521 if (ce == 'b')
522 goto start;
523 }
524 case '8':
525 system("cls");
526 strcpy(s,"");
527 cout << "Vvedite imya fila" << endl;
528 cin >> s;
529 strcat(s, ".txt");
530 ofstream outfile(s);
531 outfile << "x y" << endl;
532 for (int i = 0; i < f8.getlength(); i ++)
533 outfile << f8.getelx(i) << " " << f8.getely(i) << endl;
534 cout << "done" << endl;
535 cout << "Nazhmite \"b\" chotibi viti" << endl;
536 cin >> ce;
537 while (true)
538 if (ce == 'b')
539 goto start;
540 }
541 }
542 return 0;
543 }
Краткое описание алгоритма: Программа ищет совместную область определения для двух заданных пользователем функций. Для каждой из них вводится шаг и первое и последнее значения. После поиска совместной области программа интерполирует две функции и создает третью функцию, в которую сохраняются результаты работы программы, то есть сложение, вычитание, деление и умножение двух изначальных функций.
Инструкция к программе: Введите поочередно первый и последний элементы функций, а также их шаги. После этого введите число, соответствующее желаемому действию (соответствие указано в меню программы).
Посмотреть программу можно здесь
1 #include <iostream>
2 #include <fstream>
3 #include <cstring>
4 #include <stdlib.h>
5
6 using namespace std;
7
8 ofstream outfile;
9
10 struct approx //структура, необходимая для функции линейной интерполяции
11 {
12 double koefficientA, koefficientB;
13 };
14
15 struct dot //структура, содержащая в себе значения координат каждой точки
16 { //по обеим осям
17 double x, y;
18 };
19
20 struct polyana //структура, содержащая номера первого и последнего элемента каждой
21 { //функции и количество элементов каждой из них
22 int a1, a2, b1, b2, k1, k2;
23 };
24
25 struct trees //структура, содержащая номер элемента и логическое значение,
26 { // отвечающее за нужность или не нужность интерполяции
27 bool pol; //при равенстве или неравенстве энных элементов двух функций
28 int n;
29 };
30 //непосредственно функция линейной интерполяции
31 double pentagon (double x1, double x, double x2, double y1, double y2)
32 {
33 return (((x - x1)/(x2- x1))*(y2 - y1) + y1);
34 }
35
36 class stars //класс, позволяющий сохранять дискретные значения функции на
37 { //определенном интервале с определенным шагом
38 private:
39
40 double a; //первое значение функции
41 double b; //последнее значение функции
42 double step; //шаг
43 int length; //длина
44 int k; //счетчик количества элементов
45
46 public:
47
48 dot *massiv;
49 stars (int _k) //конструктор для создания объекта класса - структуры
50 { //с двумя полями по количеству элементов
51 massiv = new dot [_k];
52 k = _k;
53 }
54 stars () {}; //конструктор
55 stars (double _a, double _b, double _step) //конструктор для создания объекта класса через начальный
56 //и коненый элементы с определенным шагом
57 {
58 a = _a;
59 b = _b;
60 step = _step;
61
62 length = _b - _a + 1;
63 k = 0;
64
65 for (int i = _a ; i <= _b ; i += step) //подсчет количества элементов функции
66 {
67 k++;
68 }
69
70 massiv = new dot [k]; //задание функции
71 for (int i = 0 ; i < k ; i++)
72 {
73 massiv[i].x = _a + _step * i;
74 massiv[i].y = i * 5;
75 }
76 }
77
78 void outinfile () //вывод в файл значений функции
79 {
80 outfile.open ("meow", ios :: app);
81
82 outfile << "x" << " " << "y" << endl;
83 for (int i = 0 ; i < k ; i++)
84 {
85 outfile << massiv[i].x << " " << massiv[i].y << endl;
86 }
87 outfile << endl;
88 outfile.close();
89 }
90
91 void out () //вывод на экран значений функции
92 {
93 cout << "x" << " " << "y" << endl;
94 for (int i = 0 ; i < k ; i++)
95 {
96 cout << massiv[i].x << " " << massiv[i].y << endl;
97 }
98 cout << endl;
99 }
100
101 polyana prepare (stars &h) //подготовка совместной области определения для двух функций -
102 { //той части значений множества Х, на которой будут
103 trees del; //производиться вычисления
104 polyana tmp;
105 if (massiv[0].x > h.massiv[0].x) //поиск начала совместной области определения
106 {
107 del = h.love(massiv[0].x);
108 tmp.a2 = del.n + 1;
109 tmp.a1 = 0;
110 }
111 else
112 if (massiv[0].x < h.massiv[0].x)
113 {
114 del = love(h.massiv[0].x);
115 tmp.a2 = 0;
116 tmp.a1 = del.n + 1;
117 }
118 else
119 if (massiv[0].x == h.massiv[0].x)
120 {
121 tmp.a1 = 0;
122 tmp.a2 = 0;
123 };
124
125 if (massiv[k-1].x > h.massiv[k-1].x) //поиск конца совместной области определения
126 {
127 del = h.love(massiv[k-1].x);
128 tmp.b2 = k-1;
129 tmp.b1 = del.n;
130 }
131 else
132 if (massiv[k-1].x < h.massiv[k-1].x)
133 {
134 del = h.love(massiv[k-1].x);
135 tmp.b2 = del.n;
136 tmp.b1 = k-1;
137 }
138 else
139 if (massiv[k-1].x == h.massiv[k-1].x)
140 {
141 tmp.b2 = k-1;
142 tmp.b1 = k-1;
143 };
144
145 tmp.k1 = 0;
146 for (int i = tmp.a1 ; i <= tmp.b1 ; i ++) //подсчет количества элементов первой функции
147 {
148 tmp.k1++;
149 }
150 tmp.k2 = 0;
151 for (int i = tmp.a2 ; i <= tmp.b2 ; i ++) //подсчет количества элементов второй функции
152 {
153 tmp.k2++;
154 }
155 return tmp; //возвращает первые и последние значения обеих функций и
156 } //их количества элементов
157
158 //ПЕРЕГРУЗКА ОПЕРАТОРОВ
159
160 stars operator+ (stars & v) //сложение
161 {
162 polyana tmp = prepare(v);
163 int general = tmp.k1 + tmp.k2; //общее количество элементов обеих функций
164 stars F3(general); //создание объекта класса только по количеству элементов
165 for (int i = 0 ; i < tmp.k1 ; i++) //заполнение первой части окончательного результата
166 {
167 F3.massiv[i].x = massiv[i+tmp.a1].x;
168 trees tiger = v.love(massiv[i+tmp.a1].x);
169 if (tiger.pol == true) //если значения по У в одной точке не совпадают, то интерполировать
170 {
171 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
172 F3.massiv[i].x,
173 v.massiv[tiger.n + 1].x,
174 v.massiv[tiger.n].y,
175 v.massiv[tiger.n + 1].y )
176 + massiv[i+tmp.a1].y;
177 }
178 else //иначе, просто сложить значения
179 {
180 F3.massiv[i].y = v.massiv[tiger.n].y + massiv[i+tmp.a1].y;
181 }
182
183 }
184 {
185 for (int i = tmp.k1 ; i < (general) ; i++) //заполнение второй части окончательного результата
186 {
187 F3.massiv[i].x = v.massiv[i + tmp.a2 - tmp.k1].x;
188 trees tiger = love(v.massiv[i + tmp.a2 - tmp.k1].x);
189 if (tiger.pol == true)
190 {
191 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
192 F3.massiv[i].x,
193 v.massiv[tiger.n + 1].x,
194 v.massiv[tiger.n].y,
195 v.massiv[tiger.n + 1].y )
196 + v.massiv[i+tmp.a1 - tmp.k1].y;
197 }
198 else
199 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
200 }
201
202 for (int i = 0; i < (general); i++) //сортировка
203 {
204 for (int j = 0; j < (general - 1); j ++)
205 {
206 dot temp;
207 if (F3.massiv[j].x > F3.massiv[j + 1].x)
208 {
209 temp = F3.massiv[j];
210 F3.massiv[j] = F3.massiv[j + 1];
211 F3.massiv[j + 1] = temp;
212 }
213 else //если элементы совпадают, то нужно выбросить один из них
214 if (F3.massiv[j].x == F3.massiv[j + 1].x)
215 {
216 int l = j;
217 while (l < general)
218 {
219 F3.massiv[l].x = F3.massiv[l + 1].x;
220 F3.massiv[l].y = F3.massiv[l + 1].y;
221 l++;
222 }
223 general--;
224 }
225 }
226 }
227
228
229 stars normalny (general); //создание элемента класса по длине
230 for (int i = 0; i < (general); i++)
231 {
232 normalny.massiv[i].x = F3.massiv[i].x;
233 normalny.massiv[i].y = F3.massiv[i].y;
234 }
235 a = normalny.massiv[0].x;
236 b = normalny.massiv[general].x;
237 return normalny;
238 }
239 };
240
241 stars operator* (stars & v) //умножение
242 {
243 polyana tmp = prepare(v);
244 int general = tmp.k1 + tmp.k2;
245 stars F3(tmp.k1 + tmp.k2);
246 for (int i = 0 ; i < tmp.k1 ; i++)
247 {
248 F3.massiv[i].x = massiv[i+tmp.a1].x;
249 trees tiger = v.love(massiv[i+tmp.a1].x);
250 if (tiger.pol == true)
251 {
252 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, F3.massiv[i].x,
253 v.massiv[tiger.n + 1].x, v.massiv[tiger.n].y,
254 v.massiv[tiger.n + 1].y )* (massiv[i+tmp.a1].y);
255 }
256 else
257 {
258 F3.massiv[i].y = v.massiv[tiger.n].y * massiv[i+tmp.a1].y;
259 }
260
261 }
262 {
263 for (int i = tmp.k1 ; i < (general) ; i++)
264 {
265 F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
266 trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
267 if (tiger.pol == true)
268 {
269 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
270 F3.massiv[i].x,
271 v.massiv[tiger.n + 1].x,
272 v.massiv[tiger.n].y,
273 v.massiv[tiger.n + 1].y )
274 + v.massiv[i+tmp.a1 - tmp.k1].y;
275 }
276 else
277 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
278 }
279
280 for (int i= 0; i < (general); i++)
281 {
282 for (int j = 0; j < (general - 1); j ++)
283 {
284 dot temp;
285 if (F3.massiv[j].x > F3.massiv[j+1].x)
286 {
287 temp = F3.massiv[j];
288 F3.massiv[j] = F3.massiv[j+1];
289 F3.massiv[j+1] = temp;
290 }
291 else
292 if (F3.massiv[j].x == F3.massiv[j+1].x)
293 {
294 int l = j;
295 while (l < general)
296 {
297 F3.massiv[j].x = F3.massiv[j+1].x;
298 l++;
299 }
300 general--;
301 }
302 }
303 }
304
305 for (int i = 0 ; i < general ; i++)
306 {
307
308 cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
309 }
310
311
312 stars normalny(general);
313 for (int i = 0; i < (general); i++)
314 {
315 normalny.massiv[i].x = F3.massiv[i].x;
316 normalny.massiv[i].y = F3.massiv[i].y;
317 }
318 a = normalny.massiv[0].x;
319 b = normalny.massiv[general].x;
320 return normalny;
321 }
322 };
323
324 stars operator- (stars & v) //вычитание
325 {
326 polyana tmp = prepare(v);
327 int general = tmp.k1 + tmp.k2;
328 stars F3(tmp.k1 + tmp.k2);
329 for (int i = 0 ; i < tmp.k1 ; i++)
330 {
331 F3.massiv[i].x = massiv[i+tmp.a1].x;
332 trees tiger = v.love(massiv[i+tmp.a1].x);
333 if (tiger.pol == true)
334 {
335 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, F3.massiv[i].x,
336 v.massiv[tiger.n + 1].x, v.massiv[tiger.n].y,
337 v.massiv[tiger.n + 1].y )- massiv[i+tmp.a1].y;
338 }
339 else
340 {
341 F3.massiv[i].y = v.massiv[tiger.n].y - massiv[i+tmp.a1].y;
342 }
343
344 }
345 {
346 for (int i = tmp.k1 ; i < (general) ; i++)
347 {
348 F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
349 trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
350 if (tiger.pol == true)
351 {
352 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
353 F3.massiv[i].x,
354 v.massiv[tiger.n + 1].x,
355 v.massiv[tiger.n].y,
356 v.massiv[tiger.n + 1].y )
357 + v.massiv[i+tmp.a1 - tmp.k1].y;
358 }
359 else
360 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
361 }
362
363 for (int i= 0; i < (general); i++)
364 {
365 for (int j = 0; j < (general - 1); j ++)
366 {
367 dot temp;
368 if (F3.massiv[j].x > F3.massiv[j+1].x)
369 {
370 temp = F3.massiv[j];
371 F3.massiv[j] = F3.massiv[j+1];
372 F3.massiv[j+1] = temp;
373 }
374 else
375 if (F3.massiv[j].x == F3.massiv[j+1].x)
376 {
377 int l = j;
378 while (l < general)
379 {
380 F3.massiv[j].x = F3.massiv[j+1].x;
381 l++;
382 }
383 general--;
384 }
385 }
386 }
387
388 for (int i = 0 ; i < general ; i++)
389 {
390
391 cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
392 }
393
394
395 stars normalny(general);
396 for (int i = 0; i < (general); i++)
397 {
398 normalny.massiv[i].x = F3.massiv[i].x;
399 normalny.massiv[i].y = F3.massiv[i].y;
400 }
401 a = normalny.massiv[0].x;
402 b = normalny.massiv[general].x;
403 return normalny;
404 }
405 };
406
407 stars operator/ (stars & v) //деление
408 {
409 polyana tmp = prepare(v);
410 int general = tmp.k1 + tmp.k2;
411 stars F3(tmp.k1 + tmp.k2);
412 for (int i = 0 ; i < tmp.k1 ; i++)
413 {
414 F3.massiv[i].x = massiv[i+tmp.a1].x;
415 trees tiger = v.love(massiv[i+tmp.a1].x);
416 if (tiger.pol == true)
417 {
418 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, F3.massiv[i].x,
419 v.massiv[tiger.n + 1].x, v.massiv[tiger.n].y,
420 v.massiv[tiger.n + 1].y )/ (massiv[i+tmp.a1].y);
421 }
422 else
423 {
424 F3.massiv[i].y = (v.massiv[tiger.n].y) / (massiv[i+tmp.a1].y);
425 }
426
427 }
428 {
429 for (int i = tmp.k1 ; i < (general) ; i++)
430 {
431 F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
432 trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
433 if (tiger.pol == true)
434 {
435 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
436 F3.massiv[i].x,
437 v.massiv[tiger.n + 1].x,
438 v.massiv[tiger.n].y,
439 v.massiv[tiger.n + 1].y )
440 + v.massiv[i+tmp.a1 - tmp.k1].y;
441 }
442 else
443 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
444 }
445
446 for (int i= 0; i < (general); i++)
447 {
448 for (int j = 0; j < (general - 1); j ++)
449 {
450 dot temp;
451 if (F3.massiv[j].x > F3.massiv[j+1].x)
452 {
453 temp = F3.massiv[j];
454 F3.massiv[j] = F3.massiv[j+1];
455 F3.massiv[j+1] = temp;
456 }
457 else
458 if (F3.massiv[j].x == F3.massiv[j+1].x)
459 {
460 int l = j;
461 while (l < general)
462 {
463 F3.massiv[j].x = F3.massiv[j+1].x;
464 l++;
465 }
466 general--;
467 }
468 }
469 }
470
471 for (int i = 0 ; i < general ; i++)
472 {
473
474 cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
475 }
476
477
478 stars normalny(general);
479 for (int i = 0; i < (general); i++)
480 {
481 normalny.massiv[i].x = F3.massiv[i].x;
482 normalny.massiv[i].y = F3.massiv[i].y;
483 }
484 a = normalny.massiv[0].x;
485 b = normalny.massiv[general].x;
486 return normalny;
487 }
488 };
489
490 trees love (double a) //
491 {
492 trees privet;
493 for (int i = 0; i < k; i++ )
494 if ((massiv[i].x < a)&& (a < massiv[i+1].x))
495 {
496 privet.n = i;
497 privet.pol = true;
498 return privet;
499 }
500 else
501 if (massiv[i].x == a)
502 {
503 privet.n = i;
504 privet.pol = false;
505 return privet;
506 }
507 else
508 if (massiv[i+1].x == a)
509 {
510 privet.n = i+1;
511 privet.pol = false;
512 return privet;
513 }
514 }
515
516
517 approx approximate () //функция аппроксимации
518 {
519 approx hey;
520 stars mattafix (double a, double b, double step, int k, int length);
521 double sigmaX = 0;
522 double sigmaY = 0;
523 double sigmaXY = 0;
524 double sigmaXsqrt = 0;
525 for (int i = 0; i < length; i++)
526 {
527 sigmaX += a + step * i;
528 sigmaY += b + i * 5;
529 sigmaXY += (a + step * i)*(b + i * 5);
530 sigmaXsqrt += (a + step * i)*(a + step * i);
531 }
532 hey.koefficientA = ((k * (sigmaXY) - (sigmaX*sigmaY))/(k*sigmaXsqrt - (sigmaX * sigmaX)));
533 hey.koefficientB = ((sigmaY - hey.koefficientA*sigmaX)/k);
534 return hey;
535
536
537 }
538 };
539
540 int main()
541 {
542 int tyu;
543 stars function3;
544 int firstnumber1;
545 int firstnumber2;
546 int lastnumber1;
547 int lastnumber2;
548 int step1;
549 int step2;
550 while (true)
551 {
552
553 cout << "Input 0 - vvedite parametry pervoy funkcii"<< endl;
554 cout << "Input 1 - vvedite parametry vtoroy funkcii"<< endl;
555 cout << "Input 2 - slozhenie"<< endl;
556 cout << "Input 3 - umnozhenie"<< endl;
557 cout << "Input 4 - delenie"<< endl;
558 cout << "Input 5 - vychitanie"<< endl;
559 cout << "Input 6 - aproximate"<< endl;
560 cin >> tyu ;
561
562 switch (tyu)
563 {
564 case 0:
565 { cout << "Vvedite pervy x" << endl;
566 cin >> firstnumber1;
567 cout << "Vvedite posledniy x" << endl;
568 cin >> lastnumber1;
569 cout << "Vvedite shag" << endl;
570 cin >> step1;
571 break;
572 }
573 case 1:
574 {
575 cout << "Vvedite pervy x" << endl;
576 cin >> firstnumber2;
577 cout << "Vvedite posledniy x" << endl;
578 cin >> lastnumber2;
579 cout << "Vvedite shag" << endl;
580 cin >> step2;
581 break;
582 }
583 case 2:
584 {
585 stars function1 (firstnumber1, lastnumber1, step1);
586 function1.out();
587 function1.outinfile ();
588
589 stars function2 (firstnumber2, lastnumber2, step2);
590 function2.out();
591 function2.outinfile ();
592
593 function3 = function1 + function2;
594 function3.out();
595 function3.outinfile ();
596 break;
597 }
598 case 3:
599 {
600 stars function1 (firstnumber1, lastnumber1, step1);
601 function1.out();
602 function1.outinfile ();
603
604 stars function2 (firstnumber2, lastnumber2, step2);
605 function2.out();
606 function2.outinfile ();
607
608 function3 = function1 * function2;
609 function3.out();
610 function3.outinfile ();
611 break;
612 }
613 case 4:
614 {
615 stars function1 (firstnumber1, lastnumber1, step1);
616 function1.out();
617 function1.outinfile ();
618
619 stars function2 (firstnumber2, lastnumber2, step2);
620 function2.out();
621 function2.outinfile ();
622
623 function3 = function1 / function2;
624 function3.out();
625 function3.outinfile ();
626 break;
627 }
628 case 5:
629 {
630
631 stars function1 (firstnumber1, lastnumber1, step1);
632 function1.out();
633 function1.outinfile ();
634
635 stars function2 (firstnumber2, lastnumber2, step2);
636 function2.out();
637 function2.outinfile ();
638
639 function3 = function1 - function2;
640 function3.out();
641 function3.outinfile ();
642 break;
643 }
644 case 6:
645 {
646 approx you;
647 function3.approximate();
648 outfile.open ("meow", ios :: app);
649 outfile << "Y = "<< you.koefficientA <<"* x + "<<you.koefficientB << endl;
650 outfile << endl;
651 outfile.close();
652
653
654 }
655 }
656 }
657 };
Краткое описание алгоритма : Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.
Инструкция к программе: Начальная координата и шаг,для задания координат функций,передаются при вызове методов,создающих функции.Начальный шаг,шаг интерполяции,а так же количество выводимых координат заданы глобально.Поэтому просто запускайте программу, при желании поменяйте заданные величины.
Cкачать программу можно здесь
1 #include <iostream>
2
3 using namespace std;
4
5 #define N 5//количество точек
6
7 const double l1 = 5;//задаём начальный шаг функций
8 const double l2 = 0.7;//шаг для интерполяции
9
10 class Func
11 {//класс,хранящий функцию,содержащий методы:печать,перегрузка,интерполяция,апроксимация
12
13 public:
14 Func(int size) : size_(size), ax(new double[size]), by(new double[size])//создаём два массива,заполняем нулями
15 {
16 for (int i = 0; i< size_; i++)
17 {
18 ax[i] = 0;
19 by[i] = 0; //все элементы обоих массивов обнуляются
20 }
21 }
22
23 void print()//вывод на экран
24 {
25 cout << "x: ";
26 for (int i = 0; i < size_; i++)
27 cout << ax[i] << " ";
28 cout << endl << "y: ";
29 for (int i = 0; i < size_; i++)
30 cout << by[i] << " ";
31 cout << endl;
32 }
33
34 Func &operator+(Func &f2)//функция перегрузки:cложение функций
35 {
36 Func *result = new Func(size_);//создаём результирующую функцию,равную сумме двух f2 и this
37 for (int i = 0; i < size_; i++)
38 {
39 result->ax[i] = this->ax[i];//суммируем координаты X
40 result->by[i] = f2.by[i] + this->by[i];//суммируем координаты Y
41 }
42 cout << "Sum f(x)=f1+f2:" << endl;//выводим на экран сумму функций
43 result->print();
44 return *result;
45 }
46
47 void Int(double L) //метод Интерполяции
48 {
49 int M = (this->ax[this->size_ - 1] - this->ax[0]) / L + 1; //M- количество элементов массива с координатами интерполирующей функции;
50 Func result = Func(M);//cоздаём функцию,в кторой будет храниться результат интерполяции
51 cout << "M =" << M << endl;//выводим M для проверки
52 cout << "Interpolation: " << endl;
53 int t;
54 for (int i = 1; i < M; i++)
55 {
56 result.ax[0] = this->ax[0];
57 result.ax[i] = result.ax[i - 1] + L;//интерполируем Х,прибавляя шаг к каждому предыдущему элементу
58 t = (result.ax[i - 1] - result.ax[0]) / l1;//считаем номер элемента,"левого" от искомого
59
60 //интерполируем Y по формуле
61 result.by[i] = this->by[t] + ((result.ax[i] - this->ax[t]) / (this->ax[t + 1] - this->ax[t]))*(this->by[t + 1] - this->by[t]);
62
63 }
64
65 result.print();//выводим результат
66 }
67
68 void aprox()//Апроксимация
69 {
70 double a=0;
71 for(int i=0;i<size_;i++)//считаем сумму x
72 a=this->ax[i]+a;
73
74
75 double b=0;
76 for(int i=0;i<size_;i++)//считаем сумму y
77 b=this->by[i]+b;
78
79
80 double c=0;
81 for(int i=0;i<size_;i++)//считаем сумму квадратов x
82 c=(this->ax[i])*(this->ax[i])+c;
83
84
85 double d=0;
86 for(int i=0;i<size_;i++)//считаем сумму xy
87 d=(this->ax[i])*(this->by[i])+d;
88
89
90 //затем решаем систему для у=kx+m
91 //(1)c*k+a*m=d
92 //(2)a*k+size_*m=b;
93 //k=(d-am)/с
94 //подставим в (2)
95 double m;
96 m=(b*c-a*d)/(c*size_-a*a);
97 double k;
98 k=(d-a*m)/c;
99 cout<<"aproximacia :: ";
100 cout<<"y="<<k<<"x+"<<m<<endl;
101
102 }
103
104
105 double *ax;
106 double *by;
107
108 private:
109 int size_;//размер массива
110 };
111
112
113
114
115 class Cord//класс,создающий и хранящий значение функций
116 {
117 public:
118 Cord(double x0, double s) :x0(x0), s(s)//x0-начальная координата;s-шаг
119 {
120 }
121
122 void Fyx1(Func func)//метод,считающий координаты нашей функции y=x
123 {
124 int i;
125 func.ax[0] = x0;
126 for (i = 1; i < N; i++)//считаются иксы
127 {
128 func.ax[i] = x0 + s;
129 x0 = func.ax[i];
130 }
131 for (i = 0; i<N; i++)
132 func.by[i] = func.ax[i];//считаем координаты у
133 cout << "f1 :" << endl;
134 func.print();
135 cout << endl;
136 }
137
138 void Fyx2(Func func)//метод,считающий координаты нашей функции y=x+1
139 {
140 int i;
141 func.ax[0] = x0;
142 for (i = 1; i<N; i++)//считаем иксы
143 {
144 func.ax[i] = x0 + s;
145 x0 = func.ax[i];
146 }
147 for (i = 0; i<N; i++)
148 func.by[i] = func.ax[i] + 1;//считаем игрики
149 cout << "f2 :" << endl;
150 func.print();
151 cout << endl;
152 }
153
154 private:
155 double x0;//начальная координата
156 double s;//шаг
157 };
158
159 int main()
160 {
161 Func f1(N);//создание функции f1
162 Func f2(N);//создание f2
163 Cord s1(0, l1);//cоздаём объект s1
164 Cord s2(0, l1);//cоздаём объект s2
165 s1.Fyx1(f1);//задаём координаты 1ой функции
166 s2.Fyx2(f2);//задаём координаты 2ой функции
167
168 //сложение функций:
169
170 Func f3 = f2 + f1;//есть тоже ,что и Func f3 = f2.operator+(f1);
171
172 f1.Int(l2);//Интерполируем f1 с новым шагом l2
173 f1.aprox();//Апроксимируем f1
174
175 getchar();
176 return 0;
177 }
Инструкция к программе: пользователь должен ввести начало, конец и шаг. Создается две функции. Затем на экране появляется один из знаков арифметических действий. Пользователь выбирает один из знаков. Создается третья функция. Пользователь вводит второй шаг. Функция интерполируется по этому новому шагу, а затем аппроксимируется. Краткое описание алгоритма : в классе создается две функции(с помощью массивов). Так же в классе есть такие методы: перегрузка арифм операций, интерполяция, аппроксимация, вывод массивов на экран и их сохранение в файл. Сначала создается два массива для функций. Затем с помощью перегрузки эти два массива складываются/умножаются/делятся/вычитаются и записываются опять в этот массив. В методе перегрузки сразу вызывается интерполяция и аппроксимация. Программа
1 #include <iostream>
2 #include <fstream>
3 #include "math.h"
4 using namespace std;
5 class func
6 {
7 private:
8 double *mass1, *mass, *masss ;
9 double AmountDouble, Begin, End, Step, Step2;
10 public:
11 int AmountInt;
12 func ( double _Begin, double _End, double _Step ):Begin(_Begin), End(_End), Step(_Step)
13 {
14 AmountDouble=((End-Begin)/Step)+1;///количество точек с данным шагом
15 AmountInt=static_cast<int>(AmountDouble);///так как количество это целое число, то округляем
16
17 }
18
19 void massiv1() ///создание первой функции х^3
20 {
21 mass=new double[AmountInt];
22 for (int l=0; l<AmountInt; l++)
23 {
24 mass[l] =pow((l*Step+Begin),3);
25 }
26 cout << "y=x^3 \n";
27 }
28 void massiv2() ///создание второй функции sin(x)
29 {
30 mass=new double[AmountInt];
31 for (int l=0; l<AmountInt; l++)
32 {
33 mass[l] =sin(l*Step+Begin);
34 }
35 cout << "y=sin(x) \n";
36 }
37
38 void interpolation(double __Begin, double __End, double __Step)
39 {
40
41 double NewAmount=((__End-__Begin)/__Step) + 1;///количество точек для нового шага
42 int NewAmountInt=static_cast<int>(NewAmount);
43 for (int i=0; i<NewAmountInt; i++)///i-это точки функции с новыми шагами
44 {
45 mass1 = new double[NewAmountInt];
46 double x = i*__Step+__Begin;///значения х в новых точках
47 double x0=(static_cast<int>((x-__Begin)/Step)) * Step+__Begin;///значение х в точке интерполяции
48 ///стоящей ДО новой точки
49 double x1=x0+Step;///точка интерполяции ПОСЛЕ новой точки, т.е к предыдущей прибавляем СТАРЫЙ шаг
50 int i0=(static_cast<int>((x-__Begin)/Step));///это нужно для массива, значение массива в i0 соответстует значению функции в x0
51 int i1=i0+1;
52 mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
53 cout << "y("<<i<< ") = " << mass1[i] <<endl<<endl; ///вывод интерполяции на экран
54 std::ofstream fout("Interpol.txt",ios::app);///сохранение в файл
55 fout<<i<<" "<<mass1[i]<<" \n";
56 fout.close();
57 }
58 AmountInt=NewAmountInt;
59 delete[] mass;
60 mass=mass1;
61 cout<<"end of interpol";
62 }
63
64 void approximation(double __Begin, double __End, double __Step)
65
66 {
67 double SumXMass=0;///это сумма умножений x на значение функции в этом x для всех значений
68 double SumX=0;///сумма всех значений x
69 double SumMass=0;///сумма всех значений функции в точках x
70 double SumXX=0;///сумма всех квадратов значений x
71 mass1 = new double[AmountInt];
72 double x;
73 for (int i=0; i<AmountInt; i++)
74 {
75 x=i*__Step+__Begin;///такие значения принимает x в точках по порядку i
76 SumXMass=SumXMass+x*mass[i];
77 SumX=SumX+x;
78 SumMass=SumMass+mass[i];
79 SumXX=SumXX+x*x;
80
81 }
82 double a=(SumXMass*AmountInt-SumX*SumMass)/(AmountInt*SumXX-SumX*SumX);
83 double b=(SumMass-a*SumX)/AmountInt;
84 if (b>0)
85 cout<<"approximation "<<a<<"*x+"<<b<<endl;
86 else if (b<0)
87 cout<<"approximation "<<a<<"*x"<<b<<endl;
88
89 for (int i=0; i<AmountInt; i++)
90 {
91 mass1[i] = a*(i*__Step+__Begin)+b;///такие значения принимает апроксимация
92 }
93 delete[] mass;
94 mass=mass1;
95 output();///вывод на экран
96 SaveFile("approximation.txt");///сохранение в файл
97 cout<<"end of appox";
98
99 }
100
101 func operator+( func f)///перегрузка оператора +
102 {
103 func newmass(Begin, End, Step);
104 masss=new double[AmountInt];///новая функция равная сумме данныйх функций
105 for (int i=0; i<AmountInt; i++)
106 {
107 masss[i] = mass[i] + f.mass[i];
108 }
109 delete [] mass;
110 mass=masss;
111 output();///вывод на экран резултата
112 SaveFile("f3.txt");///сохранение в файл
113 cout<<"enter new step";
114 cin>>Step2;
115 cout<<"interpolation: ";
116 interpolation(Begin,End,Step2);///интерполяция
117 cout<<" approximation: ";
118 approximation(Begin,End,Step2);///аппроксимация
119 return newmass;
120
121 }
122
123 func operator-( func f)
124 {
125 func newmass(Begin, End, Step);
126 masss=new double[AmountInt];
127 for (int i=0; i<AmountInt; i++)
128 {
129 masss[i] = mass[i] - f.mass[i];
130 }
131 delete [] mass;
132 mass = masss;
133 output();
134 SaveFile("f3.txt");
135 cout<<"enter new step";
136 cin>>Step2;
137 cout<<"interpolation: ";
138 interpolation(Begin,End,Step2);
139 cout<<" approximation: ";
140 approximation(Begin,End,Step2);
141 return newmass;
142 }
143 func operator/( func f)
144 {
145 func newmass(Begin, End, Step);
146 masss=new double[AmountInt];
147 for (int i=0; i<AmountInt; i++)
148 {
149 masss[i] = mass[i] / f.mass[i];
150 }
151 cout << " division: \n ";
152 delete [] mass;
153 mass = masss;
154 output();
155 SaveFile("f3.txt");
156 cout<<"enter new step";
157 cin>>Step2;
158 cout<<"interpolation: ";
159 interpolation(Begin,End,Step2);
160 cout<<" approximation: ";
161 approximation(Begin,End,Step2);
162 return newmass;
163 }
164 func operator*( func f)
165 {
166 func newmass(Begin, End, Step);
167 masss=new double[AmountInt];
168 for (int i=0; i<AmountInt; i++)
169 {
170 masss[i] = mass[i] * f.mass[i];
171 }
172 cout << " multiply: \n ";
173 delete [] mass;
174 mass = masss;
175 output();
176 SaveFile("f3.txt");
177 cout<<"enter new step";
178 cin>>Step2;
179 cout<<"interpolation: ";
180 interpolation(Begin,End,Step2);
181 cout<<" approximation: ";
182 approximation(Begin,End,Step2);
183 return newmass;
184 }
185
186
187 void output()///вывод функции на экран
188 {
189 for (int i=0; i<AmountInt; i++)
190 {
191 cout << "y("<<i<< ") = " << mass[i] <<endl;
192
193 }
194 }
195
196
197 void SaveFile(char filename[])///сохранение функции в файл
198 {
199 std::ofstream fout(filename);
200 for (int l=0; l<AmountInt; l++)
201 {
202 fout<<l<<" "<<mass[l]<<" \n";
203 }
204
205 fout.close();
206 }
207 };
208
209
210
211 int main()
212 {
213
214 double Begin1, End1, Step1, Step2;
215 cout<<" enter the beginning of the function ";
216 cin>>Begin1;
217 cout<<"\n enter the end of the function ";
218 cin>>End1;
219 cout<<"\n enter the step of the 1st function ";
220 cin>>Step1;
221
222 func f1(Begin1,End1,Step1);///создание первой функции
223 f1.massiv1();
224 f1.output();
225 cout<<"\n ";
226 f1.SaveFile("f1.txt");
227
228 func f2(Begin1,End1,Step1);///создание второй функции
229 f2.massiv2();
230 f2.output();
231 cout<<"\n ";
232 f2.SaveFile("f2.txt");
233 cout<<"\n";
234
235 func f3(Begin1,End1,Step1);
236
237 cout<<" \n \n choose 1 - sum , 2 - subtract, 3 - division, 4 - multiply \n";///выбор операции
238 int z;
239 cin>>z;
240 switch (z)
241 {
242 case 1:
243 {
244 f3=f1+f2;///сумма функций
245 break;
246 }
247 case 2:
248 {
249 f3=f1-f2;
250 break;
251 }
252 case 3:
253 {
254 f3=f1/f2;
255 break;
256 }
257 case 4:
258 {
259 f3=f1*f2;
260 break;
261 }
262
263 default :
264 {
265 cout<<"NOOOOO";
266 break;
267 }
268 };
269 return 0;
270 }
Инструкция к программе: пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем пользователь выбирает одну из арифметических операций, которую он хочет применить к этим функциям. Создается третья функция. После пользователь вводит второй шаг для интерполяции. Третья функция интерполируется по новому шагу, а затем аппроксимируется.
Краткое описание алгоритма: в классе при помощи массива создаются две функции, с которыми потом работает программа. Эти функции перегружаются операторами арифметических операций, где затем полученная новая функция интерполируется и аппроксимируется.
Скачать программу можно по ссылке [1].
1 #include <iostream>
2 #include <locale.h>
3 #include <math.h>
4 #include <fstream>
5 #include<iomanip>
6
7 using namespace std;
8
9 class functya ///создаем класс функции
10 {
11
12 private: ///объявляем тип переменных в привате
13 double *mass, *mass1, *mass2; ///*mass, *mass1, *mass2 -определение двумерного массива
14 double start, ending, step, step2, amountdouble; ///start-начало, ending-конец, step-шаг, amountdouble-количество точек (типа double)
15
16 public: ///объявляем тип переменных в паблике
17 int amount; ///amoun-количество точек (типа int)
18
19 functya (double _start, double _ending, double _step):start(_start),ending(_ending),step(_step) ///создаем конструктор функции с объявлением переменных
20 {
21
22 amountdouble=((ending-start)/step)+1; ///подсчитываем количество точек с заданым шагом
23 amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
24
25 }
26
27 void massiv1 () ///создаем функцию массива
28 {
29
30 mass=new double[amount]; ///создаем двумерный массив
31 for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
32 {
33 mass[l]= pow((l*step+start),3); ///при помощи массива задаем функцию с которой будем работать
34 }
35 cout<< "\n";
36 }
37
38 void massiv2 () ///создаем функцию массива
39 {
40
41 mass=new double[amount]; ///создаем двумерный массив
42 for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
43 {
44 mass[l]= pow((l*step+start),2); ///при помощи массива задаем функцию с которой будем работать
45 }
46 cout<< "\n";
47
48 }
49
50 void interpol (double __start, double __ending, double __step) ///создаем функцию интерполяция с определением переменных
51 {
52
53 double amount1=((__ending-__start)/__step)+1; ///определяем тип и подсчитываем новое количество точек с новым шагом
54 int amounti=static_cast<int>(amount1); ///преобразуем количество из типа double к типу int
55
56 for (int i=0; i<amounti; i++) ///создаем цикл от 0 до amounti-нового количества точек
57 {
58
59 mass1=new double[amounti];
60 double x = i*__step+__start; ///определяем тип и расчитываем координату Х
61 double x0=(static_cast<int>((x-__start)/step)) * step+__start;///определяем тип и расчитываем координату х
62 ///в интерполирующейся точке, которая стоит до новой точки
63 double x1=x0+step;///определяем тип и расчитываем координату х1 прибавляя к предыдущей точке шаг
64 int i0=(static_cast<int>((x-__start)/step));///определяем значение массива в i0 соответстующей значению функции в x0
65 int i1=i0+1;
66 mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
67 cout << "Х="<<i<<setw(10)<< "У= " << mass1[i] <<endl<<endl; ///выводим интерполяцию на экран
68 ofstream fout("interpol.txt",ios::app);///сохраняем в файл
69 fout<< "Х="<<i<<setw(10)<< "У="<<mass1[i]<<" \n";
70 fout.close();
71
72 }
73
74 amount=amounti;
75 delete []mass;
76 mass = mass1;
77
78 }
79
80 void aprocsimation(double __start, double __ending, double __step) ///создаем функцию апроксимация с определением переменных
81 {
82
83 int N=amount; ///определяем тип и значение переменной N (равна количеству точек с заданным шагом)
84 double SumXY=0; ///определяем тип и значение переменной SumXY ( сумма (Х*У) )
85 double SumX=0; ///определяем тип и значение переменной SumX ( сумма Х )
86 double SumY=0; ///определяем тип и значение переменной SumУ ( сумма У )
87 double Sum_Xkv=0; ///определяем тип и значение переменной Sum_Xkv ( сумма (Х*Х) )
88 double Xi; ///определяем тип переменной Xi
89
90 mass1 = new double[N]; ///создаем двумерный массив
91 for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
92 {
93
94 Xi=i*__step+__start; ///расчитываем Хi
95 SumXY=SumXY+Xi*mass[i]; ///расчитываем SumXY
96 SumX=SumX+Xi; ///расчитываем SumX
97 SumY=SumY+mass[i]; ///расчитываем SumY
98 Sum_Xkv=Sum_Xkv+Xi*Xi; ///расчитываем Sum_Xkv
99
100 }
101
102 double a=(SumXY*N-SumX*SumY)/(N*Sum_Xkv-SumX*SumX); ///определяем тип и расчитываем коэффициент перед Х в уравнении аХ+b
103 double b=(SumY-a*SumX)/N; ///определяем тип и расчитываем свободный член в уравнении аХ+b
104
105 if (b>0) ///если b положительное то
106 cout<<"Апроксимация: "<<a<<"*x+"<<b<<endl; ///выводим на экран: Апроксимация: а*Х+b
107
108 else if (b<0) ///если b отрицательно то
109 cout<<"Апроксимация: "<<a<<"*x"<<b<<endl; ///выводим на экран: Апроксимация: а*Х b
110
111 for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
112 {
113 mass1[i] = a*(i*__step+__start)+b; ///при помощи массива создаем функцию подсчета точек при апроксимации
114 }
115
116 delete[] mass;
117 mass=mass1;
118 vivod();///вывод на экран
119 zapis("aprocsimation.txt");///сохраненяем в файл
120
121 }
122
123 functya operator+ ( functya F) ///перегрузка оператора +
124 {
125
126 functya tmp(start,ending,step);
127
128 mass2=new double[amount];///создаем двумерный массив
129 for (int i=0; i<amount; i++)
130 {
131 mass2[i]=mass[i] + F.mass[i];///находим сумму двух функций
132 }
133 delete [] mass;
134 mass=mass2;
135 vivod();///выводим на экран результат
136 zapis("f3.txt");///сохраненяем в файл
137 cout<<"Введите шаг для интерполяции";
138 cin>>step2;
139 cout<<"Интерполяция: "<<"\n";
140 interpol(start,ending,step2);///вызов функции интерполяции
141 aprocsimation(start,ending,step2);///вызов функции аппроксимации
142 return tmp;
143
144 }
145
146 functya operator-( functya F)///перегрузка оператора -
147 {
148
149 functya tmp(start,ending,step);
150
151 mass2=new double[amount];///создаем двумерный массив
152 for (int i=0; i<amount; i++)
153 {
154 mass2[i]=mass[i] - F.mass[i];///находим разность двух функций
155 }
156
157 delete [] mass;
158 mass=mass2;
159 vivod();///выводим на экран результат
160 zapis("f3.txt");///сохраненяем в файл
161 cout<<"Введите шаг для интерполяции";
162 cin>>step2;
163 cout<<"Интерполяция: "<<"\n";
164 interpol(start,ending,step2);///вызов функции интерполяции
165 aprocsimation(start,ending,step2);///вызов функции аппроксимации
166 return tmp;
167
168 }
169
170 functya operator*( functya F)///перегрузка оператора *
171 {
172 functya tmp(start,ending,step);
173
174 mass2=new double[amount];///создаем двумерный массив
175 for (int i=0; i<amount; i++)
176 {
177 mass2[i]=mass[i] * F.mass[i];///находим произведение двух функций
178 }
179
180 delete [] mass;
181 mass=mass2;
182 vivod();///выводим на экран результат
183 zapis("f3.txt");///сохраненяем в файл
184 cout<<"Введите шаг для интерполяции";
185 cin>>step2;
186 cout<<"Интерполяция: "<<"\n";
187 interpol(start,ending,step2);///вызов функции интерполяции
188 aprocsimation(start,ending,step2);///вызов функции аппроксимации
189 return tmp;
190
191 }
192
193 functya operator/( functya F)///перегрузка оператора /
194 {
195
196 functya tmp(start,ending,step);
197
198 mass2=new double[amount];///создаем двумерный массив
199 for (int i=0; i<amount; i++)
200 {
201 mass2[i]=mass[i] / F.mass[i];///находим частное двух функций
202 }
203
204 delete [] mass;
205 mass=mass2;
206 vivod();///выводим на экран результат
207 zapis("f3.txt");///сохраненяем в файл
208 cout<<"Введите шаг для интерполяции ";
209 cin>>step2;
210 cout<<"Интерполяция: "<<"\n";
211 interpol(start,ending,step2);///интерполяция
212 aprocsimation(start,ending,step2);///вызов функции аппроксимации
213 return tmp;
214
215 }
216
217 void vivod ()///создаем функцию вывода на экран
218 {
219
220 for (int l=0; l<amount; l++)
221 {
222 cout<<"Х"<<l<<setw(10)<< "Y= " << mass[l] <<"\n";
223 }
224
225 }
226
227 void zapis (char Zapis[])///созданем функцию записи в файл
228 {
229
230 ofstream fout(Zapis);
231 for (int l=0; l<amount; l++)
232 {
233 fout<<"X="<<l<<setw(10)<<"Y="<<mass[l]<<" \n";
234 }
235
236 fout.close();
237
238 }
239
240 };
241
242 int main()
243 {
244
245 setlocale(LC_ALL,"RUS");
246
247 double start1, ending1, step1, step2;
248 int number;
249 cout<< "Введите начало отрезка ";
250 cin>> start1;
251 cout<< "Введите конец отрезка ";
252 cin>> ending1;
253 cout<<"Введите шаг для функций ";
254 cin>> step1;
255
256 functya F1(start1,ending1,step1);///создаем первую функцию
257 F1.massiv1();
258 F1.vivod();///выводим координаты первой функции на экран
259 F1.zapis("F1.txt");///записываем координаты первой функции в файл
260
261 cout<<"\n \n";
262
263 functya F2(start1,ending1,step1);///создаем вторую функцию
264 F2.massiv2();
265 F2.vivod();///выводим координаты второй функции на экран
266 F2.zapis("F2.txt");///записываем координаты второй функции в файл
267
268 cout<<"\n \n";
269
270 functya F3(start1, ending1, step1);
271
272 cout<<"Выберите, что вы хотите сделать с функциями: 1-найти сумму, 2-найти разность, 3-найти произведение, 4-найти частное ";
273 cin>>number;
274 cout<<"\n \n";
275
276 if(number==1)
277 {
278 F3=F1+F2;
279 }
280
281 else if (number==2)
282 {
283 F3=F1-F2;
284 }
285
286 else if (number==3)
287 {
288 F3=F1*(F2);
289 }
290
291 else if (number==4)
292 {
293 F3=F1/F2;
294 }
295
296 else
297 {
298 cout<<"Ошибка ";
299 }
300
301 return 0;
302
303 }
Инструкция к программе: пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется.
Скачать программу можно по ссылке
Метод наименьших квадратов задача состоит в том, чтобы минимизировать выражение: 1: http://mech.spbstu.ru/images/b/b0/003.png Доказано, что минимум достигается при: 2: http://mech.spbstu.ru/images/2/20/005.png записываем пункт 2 в нашу программу, находим коэффициенты и находим значение линейной функции y=ax+b, по интерполированным значениям x.
<syntaxhighlight lang="cpp" line start="1" enclose="div">
- include <iostream>
- include <math.h>
- include <iomanip>
- include<stdlib.h>
using namespace std;
class func { private:
double a/*начало*/,b/*конец*/,c/*шаг*/,k/**/,m/**/,rr/**/; int d/*переменная для изменения типа, кол-во элементов для начальных элементов*/,tt/*переменная для изиенения типа, кол-ва элементов для счёта суммы*/; double *F/*массив для значений У*/, *X/*Массив для значений Х*/, *R/*массив для значений У после интерполяции*/, *Q;
public:
func (double a1, double b1, double c1):a(a1),b(b1),c(c1)//создаём конструктор для функции { double p = (b-a)/c; d = (int)p; if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива else d += 1;
F = new double [d];//создание динамического массива для У X = new double [d];// создание динамического массива для Х X[0]=a;//первый элемент X[d-1]=b;//последний элемент, для того чтобы последний элемент был в конце промежутка, чтобы его не потерять for(int i = 1; i < d-1; i++) X[i]=a+c*i; //присваивание значений всех Х
} void first ()//функция для первой функции { double y;//в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива F[0]=pow(2,a);//объявление значения У для начала промежутка F[d-1]=pow(2,b);//объявление значения У для конца промежутка for(int i = 1; i < d-1; ++i) { y = pow(2,((c*i)+a));//высчитываем значения У внутри промежутка F[i] = y;//присваиваем массиву значения по У }
cout << " " << endl;//пробел и конец строки }
void second ()//функция для второй функции { if(a==0 || b==0) return; F[0]=1*a*a; //присваивание значения функции в начале промежутка F[d-1]=1*b*b;//присваивание значения функции в конце промежутка
for(int k = 1; k <d-1; ++k) { double n = c*k+a; if (n != 0)//условие неделимости на ноль { F[k] = 1*n*n; } }
}
void operator +(func Q)//перегрузка оператора + { sum(Q); }
void sum (func Q)//функция суммирования функций на интерполированном шаге { double m, p = (b-a)/c; int i; R=new double[d+2]; if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива else d += 1; m=a; cerr<<"\n";
for(i = 0; i <d-1; ++i)//цикл суммирования функций и вывода значений суммы, функций и иксов {
cerr <<"YFirst: "<< F[i] << " "; cerr << "YSecond: "<< Q.F[i] << " "; R[i] = F[i] + Q.F[i]; cerr << "Ysum: "<< R[i] << " "; cerr << "X:" << m << '\n';
m=m+c; } for(i = 0; i <d-1; ++i) {Q.F[i]=R[i];
}
cerr << " " << endl; }
double interp( double pnt/*новый шаг*/, func Q)//функция для интерполяции функции {double p,h,i,w,*X,aApr,bApr,X2sm,XYsm,Xsm/*хранит сумму интерполированных иксов*/,Ysm/*хранит сумму интерполированных игреков*/; int q,k,l,o; p=(b-a)/pnt+1; q=int(p); R=new double [q]; X=new double [q];
l=0; k=0;
for(h=a/*начало функции*/; h<=b/*конец функции*/; h=h+c/*старый шаг*/) //шагает по нормальному шагу { for(i=a-1; i<=b; i=i+pnt/*новый шаг*/) if((i>h)&&(i<=(h+c)))//проверяет лежит ли новый шаг между точками старого { R[k]=(Q.F[l]-Q.F[l-1])*(i-h)/c+Q.F[l-1];//формула интерполяции cout<<"\n"<<"Yinter: "<<R[k]<<" "<<"X: "<<i-1;//вывод интерполированных значений и иксов X[k]=i-1; k++; } l++; } cout<<"\n"; cout<<"\n"; cout<<"\n"; //обнуление значений сумм для МНК Xsm=0; Ysm=0; XYsm=0; X2sm=0;
for(o=0;o<=k;o++)//цикл подготавливает суммы для МНК {Xsm+=X[o]; Ysm+=R[o]; XYsm+=X[o]*R[o]; X2sm+=X[o]*X[o]; }
aApr=(k*XYsm-Xsm*Ysm)/(k*X2sm-Xsm*Xsm);//находим коэфициенты по МНК bApr=(Ysm-a*Xsm)/k; cout<<"\n"<<"aAprox"<<a<<" "<<"bAprox"<<b<<"\n";//выводим их
for(o=0;o<k;o++) {c=aApr*X[o]+bApr;//считаем значение Y при данных коэфициентах cout<<"YAprox: "<<c<<" "<<"X:"<<X[o]<<"\n" ; }
return 0;}
};
int main(){
double x, xn, s1,pnt; cout << "Input the beginning of the function: " << endl; cin >> x; cout << "Input the ending of the function: " << endl; cin >> xn; cout << "Input step for the function: " << endl; cin >> s1; func H(x,xn,s1); H.first(); func G(x,xn,s1); G.second(); H+G; cout<<"\n" << "Input new step for the function: " << endl; cin >> pnt; H.interp(pnt,G);return 0;}