Информатика: Функции
Материал из Department of Theoretical and Applied Mechanics
Версия от 22:44, 22 декабря 2015; Станислав Лебедев (обсуждение | вклад)
Описание программы: программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.
Пояснения к алгоритму:
- Прочитанные из файла функции нужно отсортировать.
- Найти совместную область определения, то есть, найти множество пересечения областей определения функций, над которыми совершается операция.
- Создать третью функцию, со следующими свойствами : область определения состоит только из точек, принадлежащих совместной области определения, каждая точка области значений является результатом нужной операции над точкой области значений одной из функций и,либо интерполированной точкой по другой функции,либо,если есть возможность,точным значением из ее области значений.
Скачать можно тут.
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 }