Редактирование: Информатика: Функции
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
− | '''[[ | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > |
+ | '''[[Лебедев Станислав]]''' | ||
− | ''' | + | '''Описание программы''': программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл. |
− | ''' | + | '''Пояснения к алгоритму''': |
+ | # Прочитанные из файла функции нужно отсортировать. | ||
+ | # Найти совместную область определения, то есть, найти множество пересечения областей определения функций, над которыми совершается операция. | ||
+ | # Создать третью функцию, со следующими свойствами : область определения состоит только из точек, принадлежащих совместной области определения, каждая точка области значений является результатом нужной операции над точкой области значений одной из функций и, либо интерполированной точкой по другой функции, либо, если есть возможность, точным значением из ее области значений. | ||
− | + | Скачать можно [http://tm.spbstu.ru/Файл:Функции.rar тут]. | |
− | |||
− | |||
− | |||
− | |||
− | |||
<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"> | ||
− | |||
#include <iostream> | #include <iostream> | ||
+ | #include <math.h> | ||
+ | #include <cstring> | ||
+ | #include <cmath> | ||
+ | #include <malloc.h> | ||
#include <fstream> | #include <fstream> | ||
− | + | ||
using namespace std; | using namespace std; | ||
− | + | ||
+ | double base(double x) //базовая функция ( если задавать через шаг и начальный х | ||
{ | { | ||
− | + | return x; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | struct ap //две одинаковые структуры это нехорошо,коненчо,но зато наглядно... | |
− | + | { | |
− | + | double k,b; | |
− | + | }; | |
− | + | ||
− | + | struct fun //один столбик в таблице функции | |
− | + | { | |
− | + | double x,y; | |
− | + | }; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | struct sf //структура нужная, для возражеия значений из функции "prepare" класса F | |
− | + | { | |
+ | int i1,i2,e1,e2; | ||
+ | double glength, gfirstx, glastx; | ||
+ | }; | ||
− | + | double intr(double x1,double x2,double x,double y1,double y2) // линенейная интерполяция | |
− | + | { | |
− | + | return ( ((x-x1)/(x2-x1)) * (y2-y1) + y1 ); | |
− | + | } | |
− | + | ||
− | + | ap aproks(fun b [],int n) //линейная аппроксимация | |
− | + | { | |
− | + | ap r; | |
− | + | double xy = 0,x = 0,y = 0,sqx = 0,xsq = 0; | |
− | + | for (int i = 0; i < n; i++) //вычисление коэффицентов | |
− | + | { | |
− | + | xy += b[i].x*b[i].y; | |
− | + | x += b[i].x; | |
− | + | y += b[i].y; | |
− | + | sqx += b[i].x*b[i].x; | |
− | + | xsq += b[i].x; | |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | xsq *= xsq; | ||
− | + | r.k = (n*xy - x*y)/(n*sqx - xsq); //использование формул | |
+ | r.b = (y - r.k*x)/n; | ||
+ | return r; | ||
+ | } | ||
+ | class F | ||
+ | { | ||
+ | private: | ||
+ | int length; | ||
+ | double firstx, step, lastx; | ||
+ | fun *a; | ||
+ | public: | ||
+ | F(){} | ||
+ | F(int l,double f,double s) //конструктор, создающий фунцию по длине,первоиу элементу,шагу по х, y вычисляется по базовой функции | ||
{ | { | ||
− | + | if (l >= 0) | |
− | + | a = new fun [l]; | |
− | + | firstx = f; | |
− | + | length = l; | |
− | + | step = s; | |
− | + | lastx = firstx+(length - 1)*step; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | for (int i=0; i< | + | for (int i = 0;i < length; i ++) |
{ | { | ||
− | + | a[i].y = base(firstx + i*step); | |
+ | a[i].x = firstx + i*step; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | F (fun b[],int l) //конструктор для создания фунции с уже известными областями определния и значений | |
+ | { | ||
+ | length = l; | ||
+ | a = new fun [l]; | ||
+ | for (int i = 0; i < l;i++) | ||
+ | a[i] = b[i]; | ||
+ | |||
+ | for (int i = 0; i < l;i++) | ||
+ | for (int j = 0; j < (l - 1); j++) | ||
+ | if (a[j].x > a[j + 1].x) | ||
+ | { | ||
+ | fun tmp = a[j]; | ||
+ | a[j] = a[j + 1]; | ||
+ | a[j + 1] = a[j]; | ||
+ | } | ||
+ | |||
+ | firstx = a[0].x; | ||
+ | lastx = a[length - 1].x; | ||
+ | } | ||
+ | |||
+ | void addpar (double k, double b, int l, fun z[] ) //позволяет создать и заполнить переданным массивом поле объекта класса | ||
{ | { | ||
− | + | a = new fun [l]; | |
− | + | for (int i = 0; i < l; i++) | |
− | for (int i=0; i< | ||
{ | { | ||
− | + | a[i].y = k*z[i].x + b; | |
+ | a[i].x = z[i].x; | ||
} | } | ||
− | + | length = l; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | double getelx(int i) //возращает значение из поля "х" iого элемента | ||
+ | { | ||
+ | return a[i].x; | ||
} | } | ||
− | + | ||
+ | double getely(int i) //возращает значение из поля "х" iого элемента | ||
{ | { | ||
− | + | return a[i].y; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | ||
+ | int getlength() //возращает размер области определения функции(в точках) | ||
{ | { | ||
− | + | return length; | |
− | + | } | |
− | + | ||
− | + | void FOut() //выводит функцию на экран | |
− | + | { | |
− | + | cout << " x y" << endl; | |
− | + | for (int i = 0;i < length; i ++) | |
− | + | cout << " " << a[i].x << " " << a[i].y << endl; | |
− | + | cout << endl; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | ||
+ | |||
+ | int pfind(double x)const //возращает либо номер элемента,идущщий перед элементом, большим,чем х; в случае нахождения равного, возращает число, противоположное номеру следующего элемента(иначе может вернуться нуль,а нуль знака не имееет) | ||
{ | { | ||
− | + | for (int i = 0; i < length-1; i++ ) | |
− | |||
− | for (int i=0; i< | ||
{ | { | ||
− | + | if (((a[i].x < x) && (a[i + 1].x > x))) | |
+ | return (i + 1); | ||
+ | else | ||
+ | // чтобы иметь возможность проанализировать полученное значение функции,мы должны понимать, было найденно равное или промежуточное значение. "флагом" равных значений является знак минус,но так у нуля нет знака,то приходиться все сдвигать на 1 | ||
+ | if (a[i].x == x) | ||
+ | return -(i + 1); | ||
+ | else | ||
+ | if (a[i + 1].x == x) | ||
+ | return -(i + 2); | ||
} | } | ||
− | + | // cerr << "fail!!" << endl; | |
− | + | return -1; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | return | ||
} | } | ||
− | + | sf prepare(F &x)const //"подготовка" функций к бинарной операции (нахождение совместной области определения | |
− | |||
{ | { | ||
− | + | sf r; | |
+ | if (a[0].x > x.a[0].x) | ||
{ | { | ||
− | + | r.gfirstx = a[0].x; | |
− | + | r.i1 = 0; | |
+ | r.i1 = 0; | ||
+ | double k = x.pfind(a[0].x); | ||
+ | if (k < 0) | ||
+ | r.i2 = -k - 1; | ||
+ | else | ||
+ | r.i2 = (k - 1) + 1; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | r.gfirstx = x.a[0].x; | ||
+ | double k = pfind(x.a[0].x); | ||
+ | if (k < 0) | ||
+ | r.i1 = -k - 1; | ||
+ | else | ||
+ | r.i1 = (k - 1) + 1; | ||
+ | r.i2 = 0; | ||
} | } | ||
− | |||
− | + | if (a[length - 1].x < x.a[x.length - 1].x) | |
− | + | { | |
− | + | r.glastx = a[length - 1].x; | |
− | + | r.e1 = length - 1; | |
− | + | double k = x.pfind(r.glastx); | |
+ | if (k < 0) | ||
+ | r.e2 = -k - 1; | ||
+ | else | ||
+ | r.e2 = (k - 1) - 1; | ||
+ | } | ||
+ | else | ||
{ | { | ||
− | + | r.glastx = x.a[x.length - 1].x; | |
+ | double k = pfind(r.glastx); | ||
+ | if (k < 0) | ||
+ | r.e1 = -k - 1; | ||
+ | else | ||
+ | r.e1 = (k - 1) + 1; | ||
+ | r.e2 = x.length - 1; | ||
} | } | ||
+ | r.glength = length + x.length - r.i1 - (length - (r.e1 + 1)) - r.i2 - (x.length - (r.e2 + 1)); | ||
− | + | return r; | |
} | } | ||
− | |||
+ | void ad (fun b[],int l) //присвоить массиву объекта класса F значения массива b | ||
+ | { | ||
+ | length = l; | ||
+ | a = new fun [l]; | ||
+ | for (int i = 0; i < l;i++) | ||
+ | a[i] = b[i]; | ||
+ | firstx = a[0].x; | ||
+ | lastx = a[length - 1].x; | ||
+ | } | ||
+ | fun *geta() //получения указателя на начало массива в поле класса | ||
+ | { | ||
+ | return a; | ||
+ | } | ||
− | + | F operator +(F &x) const //сложение двух функций | |
− | { | + | { |
+ | int i1, e1, i2, e2, kk = 0; | ||
+ | double gfirstx, glastx, glength; | ||
− | + | if (((x.lastx < firstx) && (x.firstx < firstx)) || ((lastx < x.firstx) && (firstx < x.firstx))) | |
− | + | { | |
− | + | cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl; | |
− | + | F fl(-1,0,0); | |
− | + | return fl; | |
− | + | } | |
− | + | sf r = prepare(x); | |
− | + | F tmp(r.glength,r.gfirstx,r.glastx); | |
− | + | for (int i = 0; i <= (r.e1 - r.i1); i++) | |
− | + | { | |
− | + | tmp.a[i].x = a[i + r.i1].x; //поправка,введенная таким образом,чтобы номер,с которого начинается отсчет был первым в новой области определения | |
− | + | int ii = x.pfind(tmp.a[i].x); | |
− | + | if (ii < 0) | |
+ | tmp.a[i].y = x.a[-ii - 1].y + a[i + r.i1].y; | ||
+ | else | ||
+ | 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; | ||
+ | } | ||
+ | for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++) | ||
+ | { | ||
+ | int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x); | ||
+ | if (ii >= 0) | ||
+ | { | ||
+ | tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x; | ||
+ | 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; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | kk++; | ||
+ | glength --; | ||
+ | tmp.length --; | ||
+ | } | ||
+ | } | ||
− | + | for (int i = 0; i < glength; i++) | |
− | + | for (int j = 0; j < glength - 1; j++) | |
− | + | if (tmp.a[j].x > tmp.a[j + 1].x) | |
− | + | { | |
− | + | fun t = tmp.a[j]; | |
− | + | tmp.a[j] = tmp.a[j + 1]; | |
+ | tmp.a[j + 1] = t; | ||
+ | } | ||
− | + | return tmp; | |
+ | } | ||
− | + | F operator *(F & x) const //умножение двух функций | |
− | |||
− | |||
− | |||
{ | { | ||
− | + | int i1, e1, i2, e2, kk = 0; | |
− | + | double gfirstx, glastx, glength; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx))) | |
− | + | { | |
− | + | cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl; | |
− | + | F fl(-1,0,0); | |
− | + | return fl; | |
− | + | } | |
− | |||
− | } | ||
+ | sf r = prepare(x); | ||
+ | F tmp(r.glength,r.gfirstx,r.glastx); | ||
− | < | + | for (int i = 0; i <= (r.e1 - r.i1); i++) |
− | < | + | { |
+ | tmp.a[i].x = a[i + r.i1].x; | ||
+ | int ii = x.pfind(tmp.a[i].x); | ||
+ | if (ii < 0) | ||
+ | tmp.a[i].y = x.a[-ii - 1].y * a[i + r.i1].y; | ||
+ | else | ||
+ | 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; | ||
+ | } | ||
+ | for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++) | ||
+ | { | ||
+ | int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x); | ||
+ | if (ii >= 0) | ||
+ | { | ||
+ | tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x; | ||
+ | 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; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | kk++; | ||
+ | glength --; | ||
+ | tmp.length --; | ||
+ | } | ||
+ | } | ||
− | + | for (int i = 0; i < glength; i++) | |
− | + | for (int j = 0; j < glength - 1; j++) | |
− | + | if (tmp.a[j].x > tmp.a[j + 1].x) | |
+ | { | ||
+ | fun t = tmp.a[j]; | ||
+ | tmp.a[j] = tmp.a[j + 1]; | ||
+ | tmp.a[j + 1] = t; | ||
+ | } | ||
− | + | return tmp; | |
+ | } | ||
− | + | F operator ^(F & x) const //возведение функции слева от оператора в степень функции справа от оператора | |
+ | { | ||
+ | int i1, e1, i2, e2, kk = 0; | ||
+ | double gfirstx, glastx, glength; | ||
+ | if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx))) | ||
+ | { | ||
+ | cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl; | ||
+ | F fl(-1,0,0); | ||
+ | return fl; | ||
+ | } | ||
− | + | sf r = prepare(x); | |
+ | F tmp(r.glength,r.gfirstx,r.glastx); | ||
− | + | for (int i = 0; i <= (r.e1 - r.i1); i++) | |
− | + | { | |
− | + | tmp.a[i].x = a[i + r.i1].x; | |
− | + | int ii = x.pfind(tmp.a[i].x); | |
− | + | if (ii < 0) | |
− | + | tmp.a[i].y = pow(x.a[-ii - 1].y, a[i + r.i1].y); | |
− | < | + | else |
− | + | 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); | |
− | + | } | |
− | + | for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++) | |
− | + | { | |
− | + | int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x); | |
− | + | if (ii >= 0) | |
− | + | { | |
+ | tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x; | ||
+ | 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); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | kk++; | ||
+ | glength --; | ||
+ | tmp.length --; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | for (int i = 0; i < glength; i++) | ||
+ | for (int j = 0; j < glength - 1; j++) | ||
+ | if (tmp.a[j].x > tmp.a[j + 1].x) | ||
+ | { | ||
+ | fun t = tmp.a[j]; | ||
+ | tmp.a[j] = tmp.a[j + 1]; | ||
+ | tmp.a[j + 1] = t; | ||
+ | } | ||
− | + | return tmp; | |
+ | } | ||
+ | }; | ||
− | + | int main() | |
{ | { | ||
+ | /* | ||
+ | F f1(5,-2,1.5); | ||
+ | F f2(30,-10,0.5); | ||
+ | F f3, f4; | ||
+ | f1.FOut(); | ||
+ | f2.FOut(); | ||
+ | f3 = f1 + f2; | ||
+ | f3.FOut(); | ||
+ | f4 = f1 * f2; | ||
+ | f4.FOut(); | ||
+ | cout << " ________" << endl; | ||
+ | */ | ||
+ | char vc, s[255], ce; | ||
+ | ifstream infile; | ||
+ | int n; | ||
+ | fun *a; | ||
+ | F f5,f6,f7,f8,f9; | ||
− | + | while(true) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | start : | |
− | + | system("cls"); | |
− | + | cout << "1 - Vvesti 1uu func" << endl; | |
− | + | cout << "2 - Vvesti 2uu func" << endl; | |
− | + | cout << "3 - Sloshit'" << endl; | |
− | + | cout << "4 - Umnozhit'" << endl; | |
− | { | + | cout << "5 - Vozvesti v stepen'" << endl; |
− | + | cout << "6 - Aproximirovat'" << endl; | |
− | + | cout << "7 - Zapics' v file func" << endl; | |
− | + | cout << "8 - Zapics' v file aprok fun" << endl; | |
− | + | cout << "0 - Vihod" << endl; | |
− | + | cin >> vc; | |
− | + | switch (vc) | |
− | + | { | |
− | + | case '0': | |
− | + | return 0 ; | |
− | + | case '1': | |
− | + | { | |
− | + | system("cls"); | |
− | + | strcpy(s,""); | |
− | + | delete []a; | |
− | + | a = NULL; | |
− | + | cout << "Vvedite imya fila" << endl; | |
− | + | cin >> s; | |
− | + | strcat(s, ".txt"); | |
− | + | infile.open(s); | |
− | + | infile >> n; | |
− | + | a = new fun [n]; | |
− | + | for(int i = 0; i < n; i ++) | |
− | + | infile >> a[i].x >> a[i].y; | |
− | + | f5.ad(a,n); | |
− | + | f5.FOut(); | |
− | + | infile.close(); | |
− | + | cout << "Nazhmite \"b\" chotibi viti" << endl; | |
− | + | cin >> ce; | |
− | + | while (true) | |
− | + | if (ce == 'b') | |
− | + | goto start; | |
− | + | } | |
− | + | case '2': | |
− | + | { | |
− | + | system("cls"); | |
− | + | strcpy(s,""); | |
− | + | delete []a; | |
− | + | a = NULL; | |
− | + | cout << "Vvedite imya fila" << endl; | |
− | + | cin >> s; | |
− | + | strcat(s, ".txt"); | |
− | + | infile.open(s); | |
− | + | infile >> n; | |
− | + | a = new fun[n]; | |
− | + | for(int i = 0; i < n; i ++) | |
− | + | infile >> a[i].x >> a[i].y; | |
− | + | f6.ad(a,n); | |
− | + | f6.FOut(); | |
− | + | infile.close(); | |
− | + | cout << "Nazhmite \"b\" chotibi viti" << endl; | |
− | + | cin >> ce; | |
− | + | while (true) | |
− | + | if (ce == 'b') | |
− | + | goto start; | |
− | + | } | |
− | + | case '3': | |
− | + | system("cls"); | |
− | + | f5.FOut(); | |
− | + | f6.FOut(); | |
− | + | f7 = f5 + f6; | |
− | + | f7.FOut(); | |
− | + | cout << "Nazhmite \"b\" chotibi viti" << endl; | |
− | + | cin >> ce; | |
− | + | while (true) | |
− | + | if (ce == 'b') | |
− | + | goto start; | |
− | + | case '4': | |
− | + | system("cls"); | |
− | + | f5.FOut(); | |
− | + | f6.FOut(); | |
− | + | f7 = f5 * f6; | |
− | + | f7.FOut(); | |
− | + | cout << "Nazhmite \"b\" chotibi viti" << endl; | |
− | + | cin >> ce; | |
− | + | while (true) | |
− | + | if (ce == 'b') | |
− | + | goto start; | |
− | + | case '5': | |
− | + | system("cls"); | |
− | + | f5.FOut(); | |
− | + | f6.FOut(); | |
− | + | f7 = f5 ^ f6; | |
− | + | f7 = f5 ^ f6; | |
− | + | f7.FOut(); | |
− | { | + | cout << "Nazhmite \"b\" chotibi viti" << endl; |
− | + | cin >> ce; | |
− | + | while (true) | |
− | + | if (ce == 'b') | |
− | + | goto start; | |
− | + | case '6': | |
− | + | { | |
− | + | system("cls"); | |
− | + | ap tmp = aproks(f7.geta(), f7.getlength()); | |
− | + | f8.addpar(tmp.k, tmp.b, f7.getlength(), f7.geta()); | |
− | + | f8.FOut(); | |
− | + | cout << "Nazhmite \"b\" chotibi viti" << endl; | |
− | + | cin >> ce; | |
− | + | while (true) | |
− | + | if (ce == 'b') | |
− | + | goto start; | |
− | + | } | |
− | + | case '7': | |
− | + | { | |
+ | system("cls"); | ||
+ | strcpy(s,""); | ||
+ | cout << "Vvedite imya fila" << endl; | ||
+ | cin >> s; | ||
+ | strcat(s, ".txt"); | ||
+ | ofstream outfile(s); | ||
+ | outfile << "x y" << endl; | ||
+ | for (int i = 0; i < f7.getlength(); i ++) | ||
+ | outfile << f7.getelx(i) << " " << f7.getely(i) << endl; | ||
+ | cout << "done" << endl; | ||
+ | cout << "Nazhmite \"b\" chotibi viti" << endl; | ||
+ | cin >> ce; | ||
+ | while (true) | ||
+ | if (ce == 'b') | ||
+ | goto start; | ||
+ | } | ||
+ | case '8': | ||
+ | system("cls"); | ||
+ | strcpy(s,""); | ||
+ | cout << "Vvedite imya fila" << endl; | ||
+ | cin >> s; | ||
+ | strcat(s, ".txt"); | ||
+ | ofstream outfile(s); | ||
+ | outfile << "x y" << endl; | ||
+ | for (int i = 0; i < f8.getlength(); i ++) | ||
+ | outfile << f8.getelx(i) << " " << f8.getely(i) << endl; | ||
+ | cout << "done" << endl; | ||
+ | cout << "Nazhmite \"b\" chotibi viti" << endl; | ||
+ | cin >> ce; | ||
+ | while (true) | ||
+ | if (ce == 'b') | ||
+ | goto start; | ||
+ | } | ||
+ | } | ||
+ | return 0; | ||
} | } | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
− | |||
− | |||
− | + | '''[[Иванова Яна]]''' | |
− | + | '''Краткое описание алгоритма''': Программа ищет совместную область определения для двух заданных пользователем функций. Для каждой из них вводится шаг и первое и последнее значения. После поиска совместной области программа интерполирует две функции и создает третью функцию, в которую сохраняются результаты работы программы, то есть сложение, вычитание, деление и умножение двух изначальных функций. | |
− | |||
− | |||
− | |||
− | |||
− | + | '''Инструкция к программе''': Введите поочередно первый и последний элементы функций, а также их шаги. После этого введите число, соответствующее желаемому действию (соответствие указано в меню программы). | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Посмотреть программу можно [http://tm.spbstu.ru/Файл:main.zip здесь] | |
− | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > | |
− | + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | |
− | |||
− | + | #include <iostream> | |
− | + | #include <fstream> | |
− | + | #include <cstring> | |
− | + | #include <stdlib.h> | |
− | |||
− | + | using namespace std; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ofstream outfile; | |
− | + | struct approx //структура, необходимая для функции линейной интерполяции | |
{ | { | ||
+ | double koefficientA, koefficientB; | ||
+ | }; | ||
− | + | struct dot //структура, содержащая в себе значения координат каждой точки | |
+ | { //по обеим осям | ||
+ | double x, y; | ||
+ | }; | ||
− | + | struct polyana //структура, содержащая номера первого и последнего элемента каждой | |
− | + | { //функции и количество элементов каждой из них | |
− | + | int a1, a2, b1, b2, k1, k2; | |
− | + | }; | |
− | |||
− | + | struct trees //структура, содержащая номер элемента и логическое значение, | |
− | + | { // отвечающее за нужность или не нужность интерполяции | |
− | + | bool pol; //при равенстве или неравенстве энных элементов двух функций | |
− | + | int n; | |
− | + | }; | |
− | + | //непосредственно функция линейной интерполяции | |
− | + | double pentagon (double x1, double x, double x2, double y1, double y2) | |
− | + | { | |
− | + | return (((x - x1)/(x2- x1))*(y2 - y1) + y1); | |
− | return | + | } |
− | + | class stars //класс, позволяющий сохранять дискретные значения функции на | |
+ | { //определенном интервале с определенным шагом | ||
+ | private: | ||
− | + | double a; //первое значение функции | |
− | + | double b; //последнее значение функции | |
+ | double step; //шаг | ||
+ | int length; //длина | ||
+ | int k; //счетчик количества элементов | ||
− | + | public: | |
− | |||
− | |||
− | |||
− | } | + | dot *massiv; |
+ | stars (int _k) //конструктор для создания объекта класса - структуры | ||
+ | { //с двумя полями по количеству элементов | ||
+ | massiv = new dot [_k]; | ||
+ | k = _k; | ||
+ | } | ||
+ | stars () {}; //конструктор | ||
+ | stars (double _a, double _b, double _step) //конструктор для создания объекта класса через начальный | ||
+ | //и коненый элементы с определенным шагом | ||
+ | { | ||
+ | a = _a; | ||
+ | b = _b; | ||
+ | step = _step; | ||
− | + | length = _b - _a + 1; | |
− | + | k = 0; | |
− | + | for (int i = _a ; i <= _b ; i += step) //подсчет количества элементов функции | |
− | + | { | |
− | + | k++; | |
− | + | } | |
− | |||
− | + | massiv = new dot [k]; //задание функции | |
+ | for (int i = 0 ; i < k ; i++) | ||
+ | { | ||
+ | massiv[i].x = _a + _step * i; | ||
+ | massiv[i].y = i * 5; | ||
+ | } | ||
+ | } | ||
− | + | void outinfile () //вывод в файл значений функции | |
+ | { | ||
+ | outfile.open ("meow", ios :: app); | ||
− | }; | + | outfile << "x" << " " << "y" << endl; |
+ | for (int i = 0 ; i < k ; i++) | ||
+ | { | ||
+ | outfile << massiv[i].x << " " << massiv[i].y << endl; | ||
+ | } | ||
+ | outfile << endl; | ||
+ | outfile.close(); | ||
+ | } | ||
− | + | void out () //вывод на экран значений функции | |
− | { | + | { |
− | + | cout << "x" << " " << "y" << endl; | |
− | + | for (int i = 0 ; i < k ; i++) | |
− | + | { | |
− | + | cout << massiv[i].x << " " << massiv[i].y << endl; | |
− | + | } | |
− | + | cout << endl; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | + | polyana prepare (stars &h) //подготовка совместной области определения для двух функций - | |
− | + | { //той части значений множества Х, на которой будут | |
− | + | trees del; //производиться вычисления | |
− | + | polyana tmp; | |
− | + | if (massiv[0].x > h.massiv[0].x) //поиск начала совместной области определения | |
− | + | { | |
− | + | del = h.love(massiv[0].x); | |
− | + | tmp.a2 = del.n + 1; | |
− | + | tmp.a1 = 0; | |
− | + | } | |
− | + | else | |
− | + | if (massiv[0].x < h.massiv[0].x) | |
− | + | { | |
+ | del = love(h.massiv[0].x); | ||
+ | tmp.a2 = 0; | ||
+ | tmp.a1 = del.n + 1; | ||
+ | } | ||
+ | else | ||
+ | if (massiv[0].x == h.massiv[0].x) | ||
+ | { | ||
+ | tmp.a1 = 0; | ||
+ | tmp.a2 = 0; | ||
+ | }; | ||
− | + | if (massiv[k-1].x > h.massiv[k-1].x) //поиск конца совместной области определения | |
+ | { | ||
+ | del = h.love(massiv[k-1].x); | ||
+ | tmp.b2 = k-1; | ||
+ | tmp.b1 = del.n; | ||
+ | } | ||
+ | else | ||
+ | if (massiv[k-1].x < h.massiv[k-1].x) | ||
+ | { | ||
+ | del = h.love(massiv[k-1].x); | ||
+ | tmp.b2 = del.n; | ||
+ | tmp.b1 = k-1; | ||
+ | } | ||
+ | else | ||
+ | if (massiv[k-1].x == h.massiv[k-1].x) | ||
+ | { | ||
+ | tmp.b2 = k-1; | ||
+ | tmp.b1 = k-1; | ||
+ | }; | ||
− | + | tmp.k1 = 0; | |
− | + | for (int i = tmp.a1 ; i <= tmp.b1 ; i ++) //подсчет количества элементов первой функции | |
− | + | { | |
− | + | tmp.k1++; | |
− | + | } | |
− | + | tmp.k2 = 0; | |
− | + | for (int i = tmp.a2 ; i <= tmp.b2 ; i ++) //подсчет количества элементов второй функции | |
− | + | { | |
+ | tmp.k2++; | ||
+ | } | ||
+ | return tmp; //возвращает первые и последние значения обеих функций и | ||
+ | } //их количества элементов | ||
− | + | //ПЕРЕГРУЗКА ОПЕРАТОРОВ | |
− | |||
− | |||
− | |||
− | + | stars operator+ (stars & v) //сложение | |
{ | { | ||
− | F3 | + | polyana tmp = prepare(v); |
− | + | int general = tmp.k1 + tmp.k2; //общее количество элементов обеих функций | |
− | + | stars F3(general); //создание объекта класса только по количеству элементов | |
− | + | for (int i = 0 ; i < tmp.k1 ; i++) //заполнение первой части окончательного результата | |
− | + | { | |
− | + | F3.massiv[i].x = massiv[i+tmp.a1].x; | |
− | + | trees tiger = v.love(massiv[i+tmp.a1].x); | |
− | + | if (tiger.pol == true) //если значения по У в одной точке не совпадают, то интерполировать | |
− | + | { | |
− | + | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, | |
− | + | F3.massiv[i].x, | |
− | + | v.massiv[tiger.n + 1].x, | |
+ | v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y ) | ||
+ | + massiv[i+tmp.a1].y; | ||
+ | } | ||
+ | else //иначе, просто сложить значения | ||
+ | { | ||
+ | F3.massiv[i].y = v.massiv[tiger.n].y + massiv[i+tmp.a1].y; | ||
+ | } | ||
− | + | } | |
+ | { | ||
+ | for (int i = tmp.k1 ; i < (general) ; i++) //заполнение второй части окончательного результата | ||
+ | { | ||
+ | F3.massiv[i].x = v.massiv[i + tmp.a2 - tmp.k1].x; | ||
+ | trees tiger = love(v.massiv[i + tmp.a2 - tmp.k1].x); | ||
+ | if (tiger.pol == true) | ||
+ | { | ||
+ | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, | ||
+ | F3.massiv[i].x, | ||
+ | v.massiv[tiger.n + 1].x, | ||
+ | v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y ) | ||
+ | + v.massiv[i+tmp.a1 - tmp.k1].y; | ||
+ | } | ||
+ | else | ||
+ | F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y; | ||
+ | } | ||
− | } | + | for (int i = 0; i < (general); i++) //сортировка |
− | + | { | |
− | < | + | for (int j = 0; j < (general - 1); j ++) |
+ | { | ||
+ | dot temp; | ||
+ | if (F3.massiv[j].x > F3.massiv[j + 1].x) | ||
+ | { | ||
+ | temp = F3.massiv[j]; | ||
+ | F3.massiv[j] = F3.massiv[j + 1]; | ||
+ | F3.massiv[j + 1] = temp; | ||
+ | } | ||
+ | else //если элементы совпадают, то нужно выбросить один из них | ||
+ | if (F3.massiv[j].x == F3.massiv[j + 1].x) | ||
+ | { | ||
+ | int l = j; | ||
+ | while (l < general) | ||
+ | { | ||
+ | F3.massiv[l].x = F3.massiv[l + 1].x; | ||
+ | F3.massiv[l].y = F3.massiv[l + 1].y; | ||
+ | l++; | ||
+ | } | ||
+ | general--; | ||
+ | } | ||
+ | } | ||
+ | } | ||
− | |||
− | + | stars normalny (general); //создание элемента класса по длине | |
+ | for (int i = 0; i < (general); i++) | ||
+ | { | ||
+ | normalny.massiv[i].x = F3.massiv[i].x; | ||
+ | normalny.massiv[i].y = F3.massiv[i].y; | ||
+ | } | ||
+ | a = normalny.massiv[0].x; | ||
+ | b = normalny.massiv[general].x; | ||
+ | return normalny; | ||
+ | } | ||
+ | }; | ||
− | + | stars operator* (stars & v) //умножение | |
− | + | { | |
− | + | polyana tmp = prepare(v); | |
− | + | int general = tmp.k1 + tmp.k2; | |
− | + | stars F3(tmp.k1 + tmp.k2); | |
− | + | for (int i = 0 ; i < tmp.k1 ; i++) | |
+ | { | ||
+ | F3.massiv[i].x = massiv[i+tmp.a1].x; | ||
+ | trees tiger = v.love(massiv[i+tmp.a1].x); | ||
+ | if (tiger.pol == true) | ||
+ | { | ||
+ | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, F3.massiv[i].x, | ||
+ | v.massiv[tiger.n + 1].x, v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y )* (massiv[i+tmp.a1].y); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | F3.massiv[i].y = v.massiv[tiger.n].y * massiv[i+tmp.a1].y; | ||
+ | } | ||
− | + | } | |
+ | { | ||
+ | for (int i = tmp.k1 ; i < (general) ; i++) | ||
+ | { | ||
+ | F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x; | ||
+ | trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x); | ||
+ | if (tiger.pol == true) | ||
+ | { | ||
+ | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, | ||
+ | F3.massiv[i].x, | ||
+ | v.massiv[tiger.n + 1].x, | ||
+ | v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y ) | ||
+ | + v.massiv[i+tmp.a1 - tmp.k1].y; | ||
+ | } | ||
+ | else | ||
+ | F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y; | ||
+ | } | ||
− | + | for (int i= 0; i < (general); i++) | |
− | 1. | + | { |
− | + | for (int j = 0; j < (general - 1); j ++) | |
− | + | { | |
− | + | dot temp; | |
− | + | if (F3.massiv[j].x > F3.massiv[j+1].x) | |
+ | { | ||
+ | temp = F3.massiv[j]; | ||
+ | F3.massiv[j] = F3.massiv[j+1]; | ||
+ | F3.massiv[j+1] = temp; | ||
+ | } | ||
+ | else | ||
+ | if (F3.massiv[j].x == F3.massiv[j+1].x) | ||
+ | { | ||
+ | int l = j; | ||
+ | while (l < general) | ||
+ | { | ||
+ | F3.massiv[j].x = F3.massiv[j+1].x; | ||
+ | l++; | ||
+ | } | ||
+ | general--; | ||
+ | } | ||
+ | } | ||
+ | } | ||
− | + | for (int i = 0 ; i < general ; i++) | |
+ | { | ||
− | '' | + | cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl; |
+ | } | ||
− | |||
− | + | stars normalny(general); | |
− | + | for (int i = 0; i < (general); i++) | |
− | + | { | |
− | + | normalny.massiv[i].x = F3.massiv[i].x; | |
− | + | normalny.massiv[i].y = F3.massiv[i].y; | |
− | + | } | |
+ | a = normalny.massiv[0].x; | ||
+ | b = normalny.massiv[general].x; | ||
+ | return normalny; | ||
+ | } | ||
+ | }; | ||
− | + | stars operator- (stars & v) //вычитание | |
+ | { | ||
+ | polyana tmp = prepare(v); | ||
+ | int general = tmp.k1 + tmp.k2; | ||
+ | stars F3(tmp.k1 + tmp.k2); | ||
+ | for (int i = 0 ; i < tmp.k1 ; i++) | ||
+ | { | ||
+ | F3.massiv[i].x = massiv[i+tmp.a1].x; | ||
+ | trees tiger = v.love(massiv[i+tmp.a1].x); | ||
+ | if (tiger.pol == true) | ||
+ | { | ||
+ | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, F3.massiv[i].x, | ||
+ | v.massiv[tiger.n + 1].x, v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y )- massiv[i+tmp.a1].y; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | F3.massiv[i].y = v.massiv[tiger.n].y - massiv[i+tmp.a1].y; | ||
+ | } | ||
− | + | } | |
− | + | { | |
− | + | for (int i = tmp.k1 ; i < (general) ; i++) | |
− | + | { | |
− | + | F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x; | |
− | + | trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x); | |
+ | if (tiger.pol == true) | ||
+ | { | ||
+ | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, | ||
+ | F3.massiv[i].x, | ||
+ | v.massiv[tiger.n + 1].x, | ||
+ | v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y ) | ||
+ | + v.massiv[i+tmp.a1 - tmp.k1].y; | ||
+ | } | ||
+ | else | ||
+ | F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y; | ||
+ | } | ||
− | + | for (int i= 0; i < (general); i++) | |
− | + | { | |
− | + | for (int j = 0; j < (general - 1); j ++) | |
− | + | { | |
− | + | dot temp; | |
− | + | if (F3.massiv[j].x > F3.massiv[j+1].x) | |
− | + | { | |
− | + | temp = F3.massiv[j]; | |
− | + | F3.massiv[j] = F3.massiv[j+1]; | |
− | + | F3.massiv[j+1] = temp; | |
− | { | + | } |
− | + | else | |
− | }; | + | if (F3.massiv[j].x == F3.massiv[j+1].x) |
+ | { | ||
+ | int l = j; | ||
+ | while (l < general) | ||
+ | { | ||
+ | F3.massiv[j].x = F3.massiv[j+1].x; | ||
+ | l++; | ||
+ | } | ||
+ | general--; | ||
+ | } | ||
+ | } | ||
+ | } | ||
− | + | for (int i = 0 ; i < general ; i++) | |
− | { | + | { |
− | |||
− | |||
− | + | cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl; | |
− | + | } | |
− | |||
− | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | stars normalny(general); | |
− | { | + | for (int i = 0; i < (general); i++) |
− | + | { | |
+ | normalny.massiv[i].x = F3.massiv[i].x; | ||
+ | normalny.massiv[i].y = F3.massiv[i].y; | ||
+ | } | ||
+ | a = normalny.massiv[0].x; | ||
+ | b = normalny.massiv[general].x; | ||
+ | return normalny; | ||
+ | } | ||
+ | }; | ||
− | + | stars operator/ (stars & v) //деление | |
− | + | { | |
− | + | polyana tmp = prepare(v); | |
− | + | int general = tmp.k1 + tmp.k2; | |
− | + | stars F3(tmp.k1 + tmp.k2); | |
− | + | for (int i = 0 ; i < tmp.k1 ; i++) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | stars () | ||
− | |||
− | |||
{ | { | ||
− | + | F3.massiv[i].x = massiv[i+tmp.a1].x; | |
− | + | trees tiger = v.love(massiv[i+tmp.a1].x); | |
− | + | if (tiger.pol == true) | |
+ | { | ||
+ | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, F3.massiv[i].x, | ||
+ | v.massiv[tiger.n + 1].x, v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y )/ (massiv[i+tmp.a1].y); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | F3.massiv[i].y = (v.massiv[tiger.n].y) / (massiv[i+tmp.a1].y); | ||
+ | } | ||
− | + | } | |
− | + | { | |
− | + | for (int i = tmp.k1 ; i < (general) ; i++) | |
− | for (int i = | + | { |
+ | F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x; | ||
+ | trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x); | ||
+ | if (tiger.pol == true) | ||
{ | { | ||
− | + | F3.massiv[i].y = pentagon (v.massiv[tiger.n].x, | |
+ | F3.massiv[i].x, | ||
+ | v.massiv[tiger.n + 1].x, | ||
+ | v.massiv[tiger.n].y, | ||
+ | v.massiv[tiger.n + 1].y ) | ||
+ | + v.massiv[i+tmp.a1 - tmp.k1].y; | ||
} | } | ||
− | + | else | |
− | + | F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y; | |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | for (int i= 0; i < (general); i++) | |
{ | { | ||
− | + | for (int j = 0; j < (general - 1); j ++) | |
− | + | { | |
− | + | dot temp; | |
− | + | if (F3.massiv[j].x > F3.massiv[j+1].x) | |
+ | { | ||
+ | temp = F3.massiv[j]; | ||
+ | F3.massiv[j] = F3.massiv[j+1]; | ||
+ | F3.massiv[j+1] = temp; | ||
+ | } | ||
+ | else | ||
+ | if (F3.massiv[j].x == F3.massiv[j+1].x) | ||
{ | { | ||
− | + | int l = j; | |
+ | while (l < general) | ||
+ | { | ||
+ | F3.massiv[j].x = F3.massiv[j+1].x; | ||
+ | l++; | ||
+ | } | ||
+ | general--; | ||
} | } | ||
− | + | } | |
− | |||
} | } | ||
− | + | for (int i = 0 ; i < general ; i++) | |
{ | { | ||
− | + | ||
− | + | cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl; | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | ||
− | { | + | stars normalny(general); |
− | + | for (int i = 0; i < (general); i++) | |
− | + | { | |
− | if (massiv[ | + | normalny.massiv[i].x = F3.massiv[i].x; |
+ | normalny.massiv[i].y = F3.massiv[i].y; | ||
+ | } | ||
+ | a = normalny.massiv[0].x; | ||
+ | b = normalny.massiv[general].x; | ||
+ | return normalny; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | trees love (double a) // | ||
+ | { | ||
+ | trees privet; | ||
+ | for (int i = 0; i < k; i++ ) | ||
+ | if ((massiv[i].x < a)&& (a < massiv[i+1].x)) | ||
{ | { | ||
− | + | privet.n = i; | |
− | + | privet.pol = true; | |
− | + | return privet; | |
} | } | ||
else | else | ||
− | if (massiv[ | + | if (massiv[i].x == a) |
{ | { | ||
− | + | privet.n = i; | |
− | + | privet.pol = false; | |
− | + | return privet; | |
} | } | ||
else | else | ||
− | + | if (massiv[i+1].x == a) | |
− | + | { | |
− | + | privet.n = i+1; | |
− | + | privet.pol = false; | |
− | } | + | return privet; |
+ | } | ||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | approx approximate () //функция аппроксимации | |
− | + | { | |
− | + | approx hey; | |
− | + | stars mattafix (double a, double b, double step, int k, int length); | |
− | + | double sigmaX = 0; | |
− | + | double sigmaY = 0; | |
− | + | double sigmaXY = 0; | |
− | + | double sigmaXsqrt = 0; | |
− | + | for (int i = 0; i < length; i++) | |
− | + | { | |
− | + | sigmaX += a + step * i; | |
− | + | sigmaY += b + i * 5; | |
+ | sigmaXY += (a + step * i)*(b + i * 5); | ||
+ | sigmaXsqrt += (a + step * i)*(a + step * i); | ||
+ | } | ||
+ | hey.koefficientA = ((k * (sigmaXY) - (sigmaX*sigmaY))/(k*sigmaXsqrt - (sigmaX * sigmaX))); | ||
+ | hey.koefficientB = ((sigmaY - hey.koefficientA*sigmaX)/k); | ||
+ | return hey; | ||
+ | |||
− | + | } | |
+ | }; | ||
− | stars | + | int main() |
+ | { | ||
+ | int tyu; | ||
+ | stars function3; | ||
+ | int firstnumber1; | ||
+ | int firstnumber2; | ||
+ | int lastnumber1; | ||
+ | int lastnumber2; | ||
+ | int step1; | ||
+ | int step2; | ||
+ | while (true) | ||
{ | { | ||
− | + | ||
− | + | cout << "Input 0 - vvedite parametry pervoy funkcii"<< endl; | |
− | + | cout << "Input 1 - vvedite parametry vtoroy funkcii"<< endl; | |
− | + | cout << "Input 2 - slozhenie"<< endl; | |
+ | cout << "Input 3 - umnozhenie"<< endl; | ||
+ | cout << "Input 4 - delenie"<< endl; | ||
+ | cout << "Input 5 - vychitanie"<< endl; | ||
+ | cout << "Input 6 - aproximate"<< endl; | ||
+ | cin >> tyu ; | ||
+ | |||
+ | switch (tyu) | ||
{ | { | ||
− | + | case 0: | |
− | + | { cout << "Vvedite pervy x" << endl; | |
− | + | cin >> firstnumber1; | |
− | + | cout << "Vvedite posledniy x" << endl; | |
− | + | cin >> lastnumber1; | |
− | + | cout << "Vvedite shag" << endl; | |
− | + | cin >> step1; | |
− | + | break; | |
− | |||
− | |||
} | } | ||
− | + | case 1: | |
{ | { | ||
− | + | cout << "Vvedite pervy x" << endl; | |
− | } | + | cin >> firstnumber2; |
+ | cout << "Vvedite posledniy x" << endl; | ||
+ | cin >> lastnumber2; | ||
+ | cout << "Vvedite shag" << endl; | ||
+ | cin >> step2; | ||
+ | break; | ||
+ | } | ||
+ | case 2: | ||
+ | { | ||
+ | stars function1 (firstnumber1, lastnumber1, step1); | ||
+ | function1.out(); | ||
+ | function1.outinfile (); | ||
− | + | stars function2 (firstnumber2, lastnumber2, step2); | |
− | + | function2.out(); | |
− | + | function2.outinfile (); | |
− | + | ||
− | + | function3 = function1 + function2; | |
− | + | function3.out(); | |
− | + | function3.outinfile (); | |
− | + | break; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | case 3: | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | stars function1 (firstnumber1, lastnumber1, step1); | |
− | + | function1.out(); | |
− | + | function1.outinfile (); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | stars function2 (firstnumber2, lastnumber2, step2); | ||
+ | function2.out(); | ||
+ | function2.outinfile (); | ||
− | + | function3 = function1 * function2; | |
− | + | function3.out(); | |
− | + | function3.outinfile (); | |
− | + | break; | |
− | + | } | |
− | + | case 4: | |
− | + | { | |
− | + | stars function1 (firstnumber1, lastnumber1, step1); | |
− | + | function1.out(); | |
− | + | function1.outinfile (); | |
− | + | ||
+ | stars function2 (firstnumber2, lastnumber2, step2); | ||
+ | function2.out(); | ||
+ | function2.outinfile (); | ||
− | + | function3 = function1 / function2; | |
− | + | function3.out(); | |
− | + | function3.outinfile (); | |
− | + | break; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | case 5: | |
{ | { | ||
− | |||
− | |||
− | + | stars function1 (firstnumber1, lastnumber1, step1); | |
− | + | function1.out(); | |
− | + | function1.outinfile (); | |
− | + | ||
− | + | stars function2 (firstnumber2, lastnumber2, step2); | |
− | + | function2.out(); | |
− | + | function2.outinfile (); | |
− | + | ||
− | + | function3 = function1 - function2; | |
− | + | function3.out(); | |
− | + | function3.outinfile (); | |
− | + | break; | |
− | |||
− | |||
} | } | ||
− | + | case 6: | |
− | + | { | |
− | + | approx you; | |
+ | function3.approximate(); | ||
+ | outfile.open ("meow", ios :: app); | ||
+ | outfile << "Y = "<< you.koefficientA <<"* x + "<<you.koefficientB << endl; | ||
+ | outfile << endl; | ||
+ | outfile.close(); | ||
+ | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
} | } | ||
+ | }; | ||
+ | |||
+ | |||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | |||
− | |||
− | |||
− | |||
− | |||
− | + | '''[[Лосева Татьяна]]''' | |
− | + | ||
− | + | '''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов. | |
− | + | ||
− | + | '''Инструкция к программе:''' Начальная координата и шаг,для задания координат функций,передаются при вызове методов,создающих функции.Начальный шаг,шаг интерполяции,а так же количество выводимых координат заданы глобально.Поэтому просто запускайте программу, при желании поменяйте заданные | |
− | + | величины. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Cкачать программу можно [http://tm.spbstu.ru/Файл:Loseva.rar здесь] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | <div class="mw-collapsible-content"> | |
− | + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | |
− | + | #include <iostream> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | using namespace std; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | #define N 5//количество точек | |
− | |||
− | + | const double l1 = 5;//задаём начальный шаг функций | |
− | + | const double l2 = 0.7;//шаг для интерполяции | |
+ | class Func | ||
+ | {//класс,хранящий функцию,содержащий методы:печать,перегрузка,интерполяция,апроксимация | ||
− | + | public: | |
− | + | Func(int size) : size_(size), ax(new double[size]), by(new double[size])//создаём два массива,заполняем нулями | |
− | + | { | |
− | + | for (int i = 0; i< size_; i++) | |
− | + | { | |
− | + | ax[i] = 0; | |
− | + | by[i] = 0; //все элементы обоих массивов обнуляются | |
− | + | } | |
− | + | } | |
− | |||
− | |||
− | + | void print()//вывод на экран | |
− | + | { | |
− | + | cout << "x: "; | |
− | + | for (int i = 0; i < size_; i++) | |
− | + | cout << ax[i] << " "; | |
− | + | cout << endl << "y: "; | |
− | + | for (int i = 0; i < size_; i++) | |
− | + | cout << by[i] << " "; | |
− | + | cout << endl; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Func &operator+(Func &f2)//функция перегрузки:cложение функций | |
− | + | { | |
− | + | Func *result = new Func(size_);//создаём результирующую функцию,равную сумме двух f2 и this | |
− | + | for (int i = 0; i < size_; i++) | |
− | + | { | |
− | + | result->ax[i] = this->ax[i];//суммируем координаты X | |
− | + | result->by[i] = f2.by[i] + this->by[i];//суммируем координаты Y | |
− | + | } | |
− | + | cout << "Sum f(x)=f1+f2:" << endl;//выводим на экран сумму функций | |
− | + | result->print(); | |
− | + | return *result; | |
− | + | } | |
− | + | ||
− | + | void Int(double L) //метод Интерполяции | |
− | + | { | |
− | + | int M = (this->ax[this->size_ - 1] - this->ax[0]) / L + 1; //M- количество элементов массива с координатами интерполирующей функции; | |
− | + | Func result = Func(M);//cоздаём функцию,в кторой будет храниться результат интерполяции | |
− | + | cout << "M =" << M << endl;//выводим M для проверки | |
+ | cout << "Interpolation: " << endl; | ||
+ | int t; | ||
+ | for (int i = 1; i < M; i++) | ||
+ | { | ||
+ | result.ax[0] = this->ax[0]; | ||
+ | result.ax[i] = result.ax[i - 1] + L;//интерполируем Х,прибавляя шаг к каждому предыдущему элементу | ||
+ | t = (result.ax[i - 1] - result.ax[0]) / l1;//считаем номер элемента,"левого" от искомого | ||
− | + | //интерполируем Y по формуле | |
− | + | 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]); | |
− | + | ||
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | result.print();//выводим результат | |
− | + | } | |
− | + | void aprox()//Апроксимация | |
− | + | { | |
+ | double a=0; | ||
+ | for(int i=0;i<size_;i++)//считаем сумму x | ||
+ | a=this->ax[i]+a; | ||
+ | |||
+ | double b=0; | ||
+ | for(int i=0;i<size_;i++)//считаем сумму y | ||
+ | b=this->by[i]+b; | ||
+ | |||
− | + | double c=0; | |
− | + | for(int i=0;i<size_;i++)//считаем сумму квадратов x | |
− | + | c=(this->ax[i])*(this->ax[i])+c; | |
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | double d=0; | |
− | + | for(int i=0;i<size_;i++)//считаем сумму xy | |
− | + | d=(this->ax[i])*(this->by[i])+d; | |
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | //затем решаем систему для у=kx+m | ||
+ | //(1)c*k+a*m=d | ||
+ | //(2)a*k+size_*m=b; | ||
+ | //k=(d-am)/с | ||
+ | //подставим в (2) | ||
+ | double m; | ||
+ | m=(b*c-a*d)/(c*size_-a*a); | ||
+ | double k; | ||
+ | k=(d-a*m)/c; | ||
+ | cout<<"aproximacia :: "; | ||
+ | cout<<"y="<<k<<"x+"<<m<<endl; | ||
+ | |||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | double *ax; | ||
+ | double *by; | ||
− | + | private: | |
+ | int size_;//размер массива | ||
}; | }; | ||
− | + | ||
+ | |||
+ | |||
+ | class Cord//класс,создающий и хранящий значение функций | ||
{ | { | ||
− | + | public: | |
− | + | Cord(double x0, double s) :x0(x0), s(s)//x0-начальная координата;s-шаг | |
− | + | { | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | void Fyx1(Func func)//метод,считающий координаты нашей функции y=x | |
− | + | { | |
− | + | int i; | |
− | + | func.ax[0] = x0; | |
− | + | for (i = 1; i < N; i++)//считаются иксы | |
− | + | { | |
− | + | func.ax[i] = x0 + s; | |
− | + | x0 = func.ax[i]; | |
− | + | } | |
− | + | for (i = 0; i<N; i++) | |
− | + | func.by[i] = func.ax[i];//считаем координаты у | |
− | + | cout << "f1 :" << endl; | |
− | + | func.print(); | |
− | + | cout << endl; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | void Fyx2(Func func)//метод,считающий координаты нашей функции y=x+1 | |
− | + | { | |
− | + | int i; | |
− | + | func.ax[0] = x0; | |
− | + | for (i = 1; i<N; i++)//считаем иксы | |
− | + | { | |
− | + | func.ax[i] = x0 + s; | |
− | + | x0 = func.ax[i]; | |
− | + | } | |
− | + | for (i = 0; i<N; i++) | |
− | + | func.by[i] = func.ax[i] + 1;//считаем игрики | |
− | + | cout << "f2 :" << endl; | |
− | + | func.print(); | |
− | + | cout << endl; | |
+ | } | ||
− | + | private: | |
− | + | double x0;//начальная координата | |
− | + | double s;//шаг | |
+ | }; | ||
− | + | int main() | |
− | + | { | |
− | + | Func f1(N);//создание функции f1 | |
− | + | Func f2(N);//создание f2 | |
− | + | Cord s1(0, l1);//cоздаём объект s1 | |
− | + | Cord s2(0, l1);//cоздаём объект s2 | |
− | + | s1.Fyx1(f1);//задаём координаты 1ой функции | |
− | + | s2.Fyx2(f2);//задаём координаты 2ой функции | |
− | + | ||
− | + | //сложение функций: | |
+ | |||
+ | Func f3 = f2 + f1;//есть тоже ,что и Func f3 = f2.operator+(f1); | ||
− | + | f1.Int(l2);//Интерполируем f1 с новым шагом l2 | |
− | + | f1.aprox();//Апроксимируем f1 | |
− | + | ||
+ | getchar(); | ||
+ | return 0; | ||
+ | } | ||
− | + | </syntaxhighlight> | |
− | + | </div> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | '''[[Андреева Полина]]''' | |
− | |||
− | |||
− | + | '''Инструкция к программе:''' пользователь должен ввести начало, конец и шаг. Создается две функции. Затем на экране появляется один из знаков арифметических действий. Пользователь выбирает один из знаков. Создается третья функция. Пользователь вводит второй шаг. Функция интерполируется по этому новому шагу, а затем аппроксимируется. | |
− | + | '''Краткое описание алгоритма :''' в классе создается две функции(с помощью массивов). Так же в классе есть такие методы: перегрузка арифм операций, интерполяция, аппроксимация, вывод массивов на экран и их сохранение в файл. Сначала создается два массива для функций. Затем с помощью перегрузки эти два массива складываются/умножаются/делятся/вычитаются и записываются опять в этот массив. В методе перегрузки сразу вызывается интерполяция и аппроксимация. | |
− | + | [http://tm.spbstu.ru/Файл:Function.rar Программа] | |
− | + | <div class="mw-collapsible-content"> | |
− | + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | #include <iostream> | ||
+ | #include <fstream> | ||
+ | #include "math.h" | ||
+ | using namespace std; | ||
+ | class func | ||
+ | { | ||
+ | private: | ||
+ | double *mass1, *mass, *masss ; | ||
+ | double AmountDouble, Begin, End, Step, Step2; | ||
+ | public: | ||
+ | int AmountInt; | ||
+ | func ( double _Begin, double _End, double _Step ):Begin(_Begin), End(_End), Step(_Step) | ||
+ | { | ||
+ | AmountDouble=((End-Begin)/Step)+1;///количество точек с данным шагом | ||
+ | AmountInt=static_cast<int>(AmountDouble);///так как количество это целое число, то округляем | ||
− | + | } | |
− | |||
− | |||
− | } | ||
+ | void massiv1() ///создание первой функции х^3 | ||
+ | { | ||
+ | mass=new double[AmountInt]; | ||
+ | for (int l=0; l<AmountInt; l++) | ||
+ | { | ||
+ | mass[l] =pow((l*Step+Begin),3); | ||
+ | } | ||
+ | cout << "y=x^3 \n"; | ||
+ | } | ||
+ | void massiv2() ///создание второй функции sin(x) | ||
+ | { | ||
+ | mass=new double[AmountInt]; | ||
+ | for (int l=0; l<AmountInt; l++) | ||
+ | { | ||
+ | mass[l] =sin(l*Step+Begin); | ||
+ | } | ||
+ | cout << "y=sin(x) \n"; | ||
+ | } | ||
− | + | void interpolation(double __Begin, double __End, double __Step) | |
− | + | { | |
− | |||
− | |||
− | + | double NewAmount=((__End-__Begin)/__Step) + 1;///количество точек для нового шага | |
− | + | int NewAmountInt=static_cast<int>(NewAmount); | |
− | + | for (int i=0; i<NewAmountInt; i++)///i-это точки функции с новыми шагами | |
− | + | { | |
− | + | mass1 = new double[NewAmountInt]; | |
− | + | double x = i*__Step+__Begin;///значения х в новых точках | |
− | + | double x0=(static_cast<int>((x-__Begin)/Step)) * Step+__Begin;///значение х в точке интерполяции | |
− | + | ///стоящей ДО новой точки | |
− | + | double x1=x0+Step;///точка интерполяции ПОСЛЕ новой точки, т.е к предыдущей прибавляем СТАРЫЙ шаг | |
− | + | int i0=(static_cast<int>((x-__Begin)/Step));///это нужно для массива, значение массива в i0 соответстует значению функции в x0 | |
− | + | int i1=i0+1; | |
− | + | mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0]; | |
− | + | cout << "y("<<i<< ") = " << mass1[i] <<endl<<endl; ///вывод интерполяции на экран | |
− | + | std::ofstream fout("Interpol.txt",ios::app);///сохранение в файл | |
− | + | fout<<i<<" "<<mass1[i]<<" \n"; | |
+ | fout.close(); | ||
+ | } | ||
+ | AmountInt=NewAmountInt; | ||
+ | delete[] mass; | ||
+ | mass=mass1; | ||
+ | cout<<"end of interpol"; | ||
+ | } | ||
+ | void approximation(double __Begin, double __End, double __Step) | ||
− | + | { | |
+ | double SumXMass=0;///это сумма умножений x на значение функции в этом x для всех значений | ||
+ | double SumX=0;///сумма всех значений x | ||
+ | double SumMass=0;///сумма всех значений функции в точках x | ||
+ | double SumXX=0;///сумма всех квадратов значений x | ||
+ | mass1 = new double[AmountInt]; | ||
+ | double x; | ||
+ | for (int i=0; i<AmountInt; i++) | ||
+ | { | ||
+ | x=i*__Step+__Begin;///такие значения принимает x в точках по порядку i | ||
+ | SumXMass=SumXMass+x*mass[i]; | ||
+ | SumX=SumX+x; | ||
+ | SumMass=SumMass+mass[i]; | ||
+ | SumXX=SumXX+x*x; | ||
− | + | } | |
+ | double a=(SumXMass*AmountInt-SumX*SumMass)/(AmountInt*SumXX-SumX*SumX); | ||
+ | double b=(SumMass-a*SumX)/AmountInt; | ||
+ | if (b>0) | ||
+ | cout<<"approximation "<<a<<"*x+"<<b<<endl; | ||
+ | else if (b<0) | ||
+ | cout<<"approximation "<<a<<"*x"<<b<<endl; | ||
− | + | for (int i=0; i<AmountInt; i++) | |
+ | { | ||
+ | mass1[i] = a*(i*__Step+__Begin)+b;///такие значения принимает апроксимация | ||
+ | } | ||
+ | delete[] mass; | ||
+ | mass=mass1; | ||
+ | output();///вывод на экран | ||
+ | SaveFile("approximation.txt");///сохранение в файл | ||
+ | cout<<"end of appox"; | ||
− | + | } | |
− | |||
− | |||
− | |||
− | + | func operator+( func f)///перегрузка оператора + | |
+ | { | ||
+ | func newmass(Begin, End, Step); | ||
+ | masss=new double[AmountInt];///новая функция равная сумме данныйх функций | ||
+ | for (int i=0; i<AmountInt; i++) | ||
+ | { | ||
+ | masss[i] = mass[i] + f.mass[i]; | ||
+ | } | ||
+ | delete [] mass; | ||
+ | mass=masss; | ||
+ | output();///вывод на экран резултата | ||
+ | SaveFile("f3.txt");///сохранение в файл | ||
+ | cout<<"enter new step"; | ||
+ | cin>>Step2; | ||
+ | cout<<"interpolation: "; | ||
+ | interpolation(Begin,End,Step2);///интерполяция | ||
+ | cout<<" approximation: "; | ||
+ | approximation(Begin,End,Step2);///аппроксимация | ||
+ | return newmass; | ||
+ | } | ||
− | + | func operator-( func f) | |
− | + | { | |
− | + | func newmass(Begin, End, Step); | |
− | + | masss=new double[AmountInt]; | |
− | + | for (int i=0; i<AmountInt; i++) | |
− | + | { | |
− | + | masss[i] = mass[i] - f.mass[i]; | |
− | + | } | |
− | + | delete [] mass; | |
− | + | mass = masss; | |
− | + | output(); | |
− | + | SaveFile("f3.txt"); | |
− | { | + | cout<<"enter new step"; |
− | + | cin>>Step2; | |
− | } | + | cout<<"interpolation: "; |
− | + | interpolation(Begin,End,Step2); | |
− | + | cout<<" approximation: "; | |
− | + | approximation(Begin,End,Step2); | |
− | + | return newmass; | |
− | + | } | |
− | + | func operator/( func f) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | func newmass(Begin, End, Step); | |
− | + | masss=new double[AmountInt]; | |
− | + | for (int i=0; i<AmountInt; i++) | |
− | + | { | |
− | + | masss[i] = mass[i] / f.mass[i]; | |
− | + | } | |
− | + | cout << " division: \n "; | |
− | + | delete [] mass; | |
− | + | mass = masss; | |
− | + | output(); | |
− | + | SaveFile("f3.txt"); | |
− | + | cout<<"enter new step"; | |
− | + | cin>>Step2; | |
− | + | cout<<"interpolation: "; | |
− | + | interpolation(Begin,End,Step2); | |
− | + | cout<<" approximation: "; | |
− | + | approximation(Begin,End,Step2); | |
− | + | return newmass; | |
− | + | } | |
− | + | func operator*( func f) | |
− | |||
− | |||
{ | { | ||
− | + | func newmass(Begin, End, Step); | |
− | + | masss=new double[AmountInt]; | |
− | + | for (int i=0; i<AmountInt; i++) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | for (int i = 0;i < | ||
{ | { | ||
− | + | masss[i] = mass[i] * f.mass[i]; | |
− | |||
} | } | ||
+ | cout << " multiply: \n "; | ||
+ | delete [] mass; | ||
+ | mass = masss; | ||
+ | output(); | ||
+ | SaveFile("f3.txt"); | ||
+ | cout<<"enter new step"; | ||
+ | cin>>Step2; | ||
+ | cout<<"interpolation: "; | ||
+ | interpolation(Begin,End,Step2); | ||
+ | cout<<" approximation: "; | ||
+ | approximation(Begin,End,Step2); | ||
+ | return newmass; | ||
+ | } | ||
− | |||
− | + | void output()///вывод функции на экран | |
{ | { | ||
− | + | for (int i=0; i<AmountInt; i++) | |
− | + | { | |
− | for (int i = 0; i < | + | cout << "y("<<i<< ") = " << mass[i] <<endl; |
− | |||
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | void | + | |
+ | void SaveFile(char filename[])///сохранение функции в файл | ||
{ | { | ||
− | + | std::ofstream fout(filename); | |
− | for (int | + | for (int l=0; l<AmountInt; l++) |
{ | { | ||
− | + | fout<<l<<" "<<mass[l]<<" \n"; | |
− | |||
} | } | ||
− | |||
− | |||
− | + | fout.close(); | |
− | |||
− | |||
} | } | ||
+ | }; | ||
− | |||
− | |||
− | |||
− | |||
− | + | int main() | |
− | + | { | |
− | |||
− | |||
− | + | double Begin1, End1, Step1, Step2; | |
− | + | cout<<" enter the beginning of the function "; | |
− | + | cin>>Begin1; | |
− | + | cout<<"\n enter the end of the function "; | |
− | + | cin>>End1; | |
− | + | cout<<"\n enter the step of the 1st function "; | |
− | + | cin>>Step1; | |
+ | func f1(Begin1,End1,Step1);///создание первой функции | ||
+ | f1.massiv1(); | ||
+ | f1.output(); | ||
+ | cout<<"\n "; | ||
+ | f1.SaveFile("f1.txt"); | ||
− | + | func f2(Begin1,End1,Step1);///создание второй функции | |
− | + | f2.massiv2(); | |
− | + | f2.output(); | |
− | + | cout<<"\n "; | |
− | + | f2.SaveFile("f2.txt"); | |
− | + | cout<<"\n"; | |
− | + | ||
− | + | func f3(Begin1,End1,Step1); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | cout<<" \n \n choose 1 - sum , 2 - subtract, 3 - division, 4 - multiply \n";///выбор операции | |
+ | int z; | ||
+ | cin>>z; | ||
+ | switch (z) | ||
{ | { | ||
− | + | case 1: | |
− | + | { | |
− | + | f3=f1+f2;///сумма функций | |
− | + | break; | |
− | + | } | |
− | + | case 2: | |
− | + | { | |
− | + | f3=f1-f2; | |
− | + | break; | |
− | + | } | |
− | + | case 3: | |
− | + | { | |
− | + | f3=f1/f2; | |
− | + | break; | |
− | + | } | |
− | + | case 4: | |
− | + | { | |
− | + | f3=f1*f2; | |
− | + | break; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | default : | |
{ | { | ||
− | + | cout<<"NOOOOO"; | |
− | + | break; | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | }; | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | </syntaxhighlight> | ||
+ | </div> | ||
− | |||
− | |||
− | |||
− | |||
− | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > | |
− | + | '''[[Белоусова Екатерина]]''' | |
− | + | ||
− | + | '''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем пользователь выбирает одну из арифметических операций, которую он хочет применить к этим функциям. Создается третья функция. После пользователь вводит второй шаг для интерполяции. Третья функция интерполируется по новому шагу, а затем аппроксимируется. | |
+ | |||
+ | '''Краткое описание алгоритма''': в классе при помощи массива создаются две функции, с которыми потом работает программа. Эти функции перегружаются операторами арифметических операций, где затем полученная новая функция интерполируется и аппроксимируется. | ||
+ | |||
+ | Скачать программу можно по ссылке [http://tm.spbstu.ru/Файл:задача_2.zip]. | ||
− | + | <div class="mw-collapsible-content"> | |
− | + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | |
− | + | #include <iostream> | |
− | + | #include <locale.h> | |
− | + | #include <math.h> | |
− | + | #include <fstream> | |
− | + | #include<iomanip> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | using namespace std; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | class functya ///создаем класс функции | |
− | + | { | |
− | + | private: ///объявляем тип переменных в привате | |
− | + | double *mass, *mass1, *mass2; ///*mass, *mass1, *mass2 -определение двумерного массива | |
− | + | double start, ending, step, step2, amountdouble; ///start-начало, ending-конец, step-шаг, amountdouble-количество точек (типа double) | |
− | + | ||
+ | public: ///объявляем тип переменных в паблике | ||
+ | int amount; ///amoun-количество точек (типа int) | ||
+ | |||
+ | functya (double _start, double _ending, double _step):start(_start),ending(_ending),step(_step) ///создаем конструктор функции с объявлением переменных | ||
+ | { | ||
+ | |||
+ | amountdouble=((ending-start)/step)+1; ///подсчитываем количество точек с заданым шагом | ||
+ | amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int | ||
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | void massiv1 () ///создаем функцию массива | |
− | + | { | |
− | + | mass=new double[amount]; ///создаем двумерный массив | |
− | + | for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек | |
− | + | { | |
− | + | mass[l]= pow((l*step+start),3); ///при помощи массива задаем функцию с которой будем работать | |
− | + | } | |
− | + | cout<< "\n"; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | void massiv2 () ///создаем функцию массива | |
− | + | { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | mass=new double[amount]; ///создаем двумерный массив | |
+ | for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек | ||
+ | { | ||
+ | mass[l]= pow((l*step+start),2); ///при помощи массива задаем функцию с которой будем работать | ||
} | } | ||
+ | cout<< "\n"; | ||
− | + | } | |
− | + | ||
− | + | void interpol (double __start, double __ending, double __step) ///создаем функцию интерполяция с определением переменных | |
− | + | { | |
− | + | double amount1=((__ending-__start)/__step)+1; ///определяем тип и подсчитываем новое количество точек с новым шагом | |
− | + | int amounti=static_cast<int>(amount1); ///преобразуем количество из типа double к типу int | |
− | |||
− | |||
− | |||
− | |||
− | + | for (int i=0; i<amounti; i++) ///создаем цикл от 0 до amounti-нового количества точек | |
− | + | { | |
− | + | mass1=new double[amounti]; | |
− | + | double x = i*__step+__start; ///определяем тип и расчитываем координату Х | |
− | + | double x0=(static_cast<int>((x-__start)/step)) * step+__start;///определяем тип и расчитываем координату х | |
− | + | ///в интерполирующейся точке, которая стоит до новой точки | |
− | + | double x1=x0+step;///определяем тип и расчитываем координату х1 прибавляя к предыдущей точке шаг | |
− | + | int i0=(static_cast<int>((x-__start)/step));///определяем значение массива в i0 соответстующей значению функции в x0 | |
− | + | int i1=i0+1; | |
− | + | mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0]; | |
− | + | cout << "Х="<<i<<setw(10)<< "У= " << mass1[i] <<endl<<endl; ///выводим интерполяцию на экран | |
− | + | ofstream fout("interpol.txt",ios::app);///сохраняем в файл | |
− | + | fout<< "Х="<<i<<setw(10)<< "У="<<mass1[i]<<" \n"; | |
− | + | fout.close(); | |
− | + | ||
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | amount=amounti; | |
− | + | delete []mass; | |
− | + | mass = mass1; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | } | |
− | |||
− | |||
− | + | void aprocsimation(double __start, double __ending, double __step) ///создаем функцию апроксимация с определением переменных | |
{ | { | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | int N=amount; ///определяем тип и значение переменной N (равна количеству точек с заданным шагом) | |
+ | double SumXY=0; ///определяем тип и значение переменной SumXY ( сумма (Х*У) ) | ||
+ | double SumX=0; ///определяем тип и значение переменной SumX ( сумма Х ) | ||
+ | double SumY=0; ///определяем тип и значение переменной SumУ ( сумма У ) | ||
+ | double Sum_Xkv=0; ///определяем тип и значение переменной Sum_Xkv ( сумма (Х*Х) ) | ||
+ | double Xi; ///определяем тип переменной Xi | ||
+ | |||
+ | mass1 = new double[N]; ///создаем двумерный массив | ||
+ | for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом) | ||
{ | { | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Xi=i*__step+__start; ///расчитываем Хi | |
− | + | SumXY=SumXY+Xi*mass[i]; ///расчитываем SumXY | |
− | + | SumX=SumX+Xi; ///расчитываем SumX | |
− | + | SumY=SumY+mass[i]; ///расчитываем SumY | |
− | + | Sum_Xkv=Sum_Xkv+Xi*Xi; ///расчитываем Sum_Xkv | |
− | + | ||
− | + | } | |
− | + | ||
− | + | double a=(SumXY*N-SumX*SumY)/(N*Sum_Xkv-SumX*SumX); ///определяем тип и расчитываем коэффициент перед Х в уравнении аХ+b | |
− | + | double b=(SumY-a*SumX)/N; ///определяем тип и расчитываем свободный член в уравнении аХ+b | |
− | + | ||
− | + | if (b>0) ///если b положительное то | |
− | + | cout<<"Апроксимация: "<<a<<"*x+"<<b<<endl; ///выводим на экран: Апроксимация: а*Х+b | |
− | + | ||
− | + | else if (b<0) ///если b отрицательно то | |
− | + | cout<<"Апроксимация: "<<a<<"*x"<<b<<endl; ///выводим на экран: Апроксимация: а*Х b | |
− | + | ||
− | + | for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом) | |
− | + | { | |
− | + | mass1[i] = a*(i*__step+__start)+b; ///при помощи массива создаем функцию подсчета точек при апроксимации | |
− | + | } | |
− | + | ||
− | + | delete[] mass; | |
− | + | mass=mass1; | |
− | + | vivod();///вывод на экран | |
− | return | + | zapis("aprocsimation.txt");///сохраненяем в файл |
+ | |||
+ | } | ||
+ | |||
+ | functya operator+ ( functya F) ///перегрузка оператора + | ||
+ | { | ||
+ | |||
+ | functya tmp(start,ending,step); | ||
+ | |||
+ | mass2=new double[amount];///создаем двумерный массив | ||
+ | for (int i=0; i<amount; i++) | ||
+ | { | ||
+ | mass2[i]=mass[i] + F.mass[i];///находим сумму двух функций | ||
+ | } | ||
+ | delete [] mass; | ||
+ | mass=mass2; | ||
+ | vivod();///выводим на экран результат | ||
+ | zapis("f3.txt");///сохраненяем в файл | ||
+ | cout<<"Введите шаг для интерполяции"; | ||
+ | cin>>step2; | ||
+ | cout<<"Интерполяция: "<<"\n"; | ||
+ | interpol(start,ending,step2);///вызов функции интерполяции | ||
+ | aprocsimation(start,ending,step2);///вызов функции аппроксимации | ||
+ | return tmp; | ||
+ | |||
+ | } | ||
+ | |||
+ | functya operator-( functya F)///перегрузка оператора - | ||
+ | { | ||
+ | |||
+ | functya tmp(start,ending,step); | ||
+ | |||
+ | mass2=new double[amount];///создаем двумерный массив | ||
+ | for (int i=0; i<amount; i++) | ||
+ | { | ||
+ | mass2[i]=mass[i] - F.mass[i];///находим разность двух функций | ||
+ | } | ||
+ | |||
+ | delete [] mass; | ||
+ | mass=mass2; | ||
+ | vivod();///выводим на экран результат | ||
+ | zapis("f3.txt");///сохраненяем в файл | ||
+ | cout<<"Введите шаг для интерполяции"; | ||
+ | cin>>step2; | ||
+ | cout<<"Интерполяция: "<<"\n"; | ||
+ | interpol(start,ending,step2);///вызов функции интерполяции | ||
+ | aprocsimation(start,ending,step2);///вызов функции аппроксимации | ||
+ | return tmp; | ||
+ | |||
+ | } | ||
+ | |||
+ | functya operator*( functya F)///перегрузка оператора * | ||
+ | { | ||
+ | functya tmp(start,ending,step); | ||
+ | |||
+ | mass2=new double[amount];///создаем двумерный массив | ||
+ | for (int i=0; i<amount; i++) | ||
+ | { | ||
+ | mass2[i]=mass[i] * F.mass[i];///находим произведение двух функций | ||
+ | } | ||
+ | |||
+ | delete [] mass; | ||
+ | mass=mass2; | ||
+ | vivod();///выводим на экран результат | ||
+ | zapis("f3.txt");///сохраненяем в файл | ||
+ | cout<<"Введите шаг для интерполяции"; | ||
+ | cin>>step2; | ||
+ | cout<<"Интерполяция: "<<"\n"; | ||
+ | interpol(start,ending,step2);///вызов функции интерполяции | ||
+ | aprocsimation(start,ending,step2);///вызов функции аппроксимации | ||
+ | return tmp; | ||
+ | |||
} | } | ||
− | |||
− | |||
− | + | functya operator/( functya F)///перегрузка оператора / | |
+ | { | ||
− | + | functya tmp(start,ending,step); | |
− | |||
− | + | mass2=new double[amount];///создаем двумерный массив | |
+ | for (int i=0; i<amount; i++) | ||
+ | { | ||
+ | mass2[i]=mass[i] / F.mass[i];///находим частное двух функций | ||
+ | } | ||
+ | delete [] mass; | ||
+ | mass=mass2; | ||
+ | vivod();///выводим на экран результат | ||
+ | zapis("f3.txt");///сохраненяем в файл | ||
+ | cout<<"Введите шаг для интерполяции "; | ||
+ | cin>>step2; | ||
+ | cout<<"Интерполяция: "<<"\n"; | ||
+ | interpol(start,ending,step2);///интерполяция | ||
+ | aprocsimation(start,ending,step2);///вызов функции аппроксимации | ||
+ | return tmp; | ||
− | + | } | |
− | |||
− | |||
− | + | void vivod ()///создаем функцию вывода на экран | |
− | + | { | |
− | + | for (int l=0; l<amount; l++) | |
+ | { | ||
+ | cout<<"Х"<<l<<setw(10)<< "Y= " << mass[l] <<"\n"; | ||
+ | } | ||
− | + | } | |
− | |||
− | |||
− | + | void zapis (char Zapis[])///созданем функцию записи в файл | |
+ | { | ||
− | + | ofstream fout(Zapis); | |
+ | for (int l=0; l<amount; l++) | ||
+ | { | ||
+ | fout<<"X="<<l<<setw(10)<<"Y="<<mass[l]<<" \n"; | ||
+ | } | ||
+ | |||
+ | fout.close(); | ||
− | + | } | |
− | |||
− | + | }; | |
− | |||
− | + | int main() | |
− | + | { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | setlocale(LC_ALL,"RUS"); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | double start1, ending1, step1, step2; | |
− | + | int number; | |
− | + | cout<< "Введите начало отрезка "; | |
− | + | cin>> start1; | |
− | + | cout<< "Введите конец отрезка "; | |
− | + | cin>> ending1; | |
− | + | cout<<"Введите шаг для функций "; | |
− | + | cin>> step1; | |
− | |||
− | |||
− | |||
− | |||
− | + | functya F1(start1,ending1,step1);///создаем первую функцию | |
− | + | F1.massiv1(); | |
− | + | F1.vivod();///выводим координаты первой функции на экран | |
− | + | F1.zapis("F1.txt");///записываем координаты первой функции в файл | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | cout<<"\n \n"; | |
− | |||
− | + | functya F2(start1,ending1,step1);///создаем вторую функцию | |
+ | F2.massiv2(); | ||
+ | F2.vivod();///выводим координаты второй функции на экран | ||
+ | F2.zapis("F2.txt");///записываем координаты второй функции в файл | ||
− | + | cout<<"\n \n"; | |
− | |||
− | + | functya F3(start1, ending1, step1); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | cout<<"Выберите, что вы хотите сделать с функциями: 1-найти сумму, 2-найти разность, 3-найти произведение, 4-найти частное "; | |
− | + | cin>>number; | |
− | + | cout<<"\n \n"; | |
− | |||
− | + | if(number==1) | |
− | + | { | |
− | + | F3=F1+F2; | |
− | + | } | |
− | + | else if (number==2) | |
− | + | { | |
− | + | F3=F1-F2; | |
− | + | } | |
− | + | else if (number==3) | |
− | + | { | |
− | + | F3=F1*(F2); | |
− | + | } | |
− | + | ||
− | + | else if (number==4) | |
− | + | { | |
− | + | F3=F1/F2; | |
− | + | } | |
− | + | ||
− | + | else | |
+ | { | ||
+ | cout<<"Ошибка "; | ||
+ | } | ||
− | + | return 0; | |
+ | } | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | '''[[Уманский Александр]]''' | ||
+ | '''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Скачать программу можно по [http://mech.spbstu.ru/File:Untitled1.rar ссылке] | |
− | + | <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"> | |
− | + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | |
− | + | ||
− | + | #include <iostream> | |
− | + | #include <math.h> | |
− | + | #include <iomanip> | |
− | + | #include<stdlib.h> | |
− | + | using namespace std; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | class func | ||
+ | { | ||
private: | 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;} | |
− | + | </syntaxhighlight> | |
− | + | </div> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > | |
− | + | '''[[Рубинова Раиса]]''' | |
− | |||
− | |||
− | |||
− | + | '''Описание программы''': программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции. | |
− | |||
− | |||
− | + | '''Инструкция к программе''': | |
− | + | 1. Пользователь вводит параметры первой функции | |
− | + | 2. Пользователь вводит параметры второй функции (при этом шаг второй функции меньше шага первой) | |
− | + | 3. Происходит интерполяция первой функции по второй | |
+ | 4. Пользователь выбирает арифметическую операцию | ||
+ | 5. При желании пользователь может выполнить аппроксимацию полученного результата | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Скачать можно [http://tm.spbstu.ru/File:Funcc.rar тут]. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | <div class="mw-collapsible-content"> | |
− | + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | |
+ | #ifndef FUNC_H | ||
+ | #define FUNC_H | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | class Func | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | public: | |
− | + | Func(double a1, double b1, double c1); | |
− | + | virtual ~Func(); | |
− | + | void DefFunc (); // функция, определяющая количество элементов j на промежутке от a до b, с шагом c | |
− | + | void PluFunc (Func D); // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной) | |
− | + | void operator +(Func D); // перегрузка оператора '+' | |
− | + | void MinFunc (Func D); // функция, линейно вычитающая значения второй функции из значений первой функции | |
− | + | void operator -(Func D); // перегрузка оператора '-' | |
− | + | void UmnFunc (Func D); // функция, линейно переумножающая значения функций | |
− | + | void operator *(Func D); // перегрузка оператора '*' | |
− | + | void DelFunc (Func D); // функция, линейно делящая значения первой функци на значения второй функции | |
− | + | void operator /(Func D); // перегрузка оператора '/' | |
− | + | void In (Func D); // функция, интерполирующая первую функцию по второй | |
− | + | void App (); // функция, аппроксимирующая полученную в результате сложения/вычитания/деления/умножения двух функций функцию | |
− | + | void Viv (); // Функция вывода на экран значений | |
− | void | + | protected: |
− | + | private: | |
− | + | double a,b,c; | |
− | + | int j,z; | |
− | + | double *A,*B; | |
− | + | }; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | / | ||
− | // | ||
− | void | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | / | + | #endif // FUNC_H |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | #include "Func.h" | |
− | + | #include <fstream> | |
− | + | #include <iostream> | |
− | + | #include <math.h> | |
− | |||
− | |||
− | |||
− | + | Func::Func(double a1, double b1, double c1):a(a1),b(b1),c(c1) // конструктор для класса Func, создающий объект данного класса, определенный тремя значениями, введенными пользователем | |
− | |||
− | |||
{ | { | ||
− | + | double d=(b-a)/c; // расчет количества элементов, определяющих функцию | |
− | + | j=floor(d); // созданной целочисленной переменной присваивается значение, равное целой части числа, рассчитанного выше, с округлением в меньшую сторону | |
− | + | A = new double [j+1]; // создание массива | |
+ | } | ||
− | + | Func::~Func() // деструктор для класса Func | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | //dtor | |
− | + | } | |
− | + | void Func::Viv () // Функция вывода на экран значений | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | std::cout << "x "; | |
− | + | for (int z=0; z<=j; ++z) | |
+ | { | ||
+ | std::cout << z+1 << " "; | ||
+ | } | ||
+ | } | ||
− | + | void Func::DefFunc () // функция, определяющая количество элементов j на промежутке от a до b, с шагом c | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | double x; // создание переменной, используемой для расчета значений функции | |
− | + | for(int i=0; i<=j; ++i) // создание цикла, рассчитывающего j элементов | |
− | + | { | |
− | + | x =i*c+a; // задание значения перемнной x, определенной выше | |
− | + | A[i]=x*x; // задание значения самой функции (при этом в данной ситуации нам неважно, как именно задается функция, ее значения могут быть определены любым способом, от этого алгоритм не меняется) | |
− | + | std::cerr << A[i] << " "; // вывод на экран значения функции | |
− | + | } | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | void Func::PluFunc (Func D) // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | std::ofstream out("zap.txt"); // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы | |
− | + | for(int i=0; i<=D.j; ++i) // создание цикла, повторяющегося (D.j+1) раз | |
− | + | { | |
− | + | B[i]=B[i]+D.A[i]; // сложение значений двух функций для одного и того же значения переменной | |
− | + | } | |
− | + | for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий | |
− | + | { | |
− | + | out << B[i] << '\n'; // запись значений, полученных в предыдущем цикле, в файл | |
− | + | } | |
− | + | out.close(); // закрытие файла после записи в него значений | |
− | + | D.Viv(); | |
− | + | std::cout << std::endl << "y "; | |
− | + | for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран | |
− | + | { | |
− | + | std::cout << B[i] << " "; | |
− | + | } | |
− | + | } | |
− | + | void Func::operator +(Func D) // перегрузка оператора '+' | |
− | + | { | |
− | + | PluFunc(D); // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1+f2 будет работать аналогично записи f1.PluFunc(f2) | |
− | + | } | |
− | + | void Func::MinFunc (Func D) // функция, линейно вычитающая значения второй функции из значений первой функции | |
− | + | { | |
− | + | std::ofstream out("zap.txt"); // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы | |
− | + | for(int i=0; i<=D.j; ++i) // создание цикла, повторяющегося (D.j+1) раз | |
− | + | { | |
− | + | B[i]=B[i]-D.A[i]; // вычитание значений второй функций из значений первой для одного и того же значения переменной | |
− | + | } | |
− | + | for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий | |
− | + | { | |
− | + | out << B[i] << '\n'; // запись значений, полученных в предыдущем цикле, в файл | |
− | + | } | |
− | + | out.close(); // закрытие файла после записи в него значений | |
− | + | D.Viv(); | |
− | + | std::cout << std::endl << "y "; | |
− | + | for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран | |
− | + | { | |
− | + | std::cout << B[i] << " "; | |
− | + | } | |
− | + | } | |
− | + | void Func::operator -(Func D) // перегрузка оператора '-' | |
− | + | { | |
− | + | MinFunc(D); // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1-f2 будет работать аналогично записи f1.MinFunc(f2) | |
− | + | } | |
− | + | void Func::UmnFunc (Func D) // функция, линейно переумножающая значения функций | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | std::ofstream out("zap.txt"); // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы | |
− | + | for(int i=0; i<=D.j; ++i) // создание цикла, повторяющегося (D.j+1) раз | |
− | + | { | |
− | + | B[i]=B[i]*D.A[i]; // умножение значений первой функций на значенийя второй для одного и того же значения переменной | |
− | + | } | |
− | + | for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий | |
− | + | { | |
− | + | out << B[i] << '\n'; // запись значений, полученных в предыдущем цикле, в файл | |
− | + | } | |
− | + | out.close(); // закрытие файла после записи в него значений | |
− | + | D.Viv(); | |
− | + | std::cout << std::endl << "y "; | |
− | + | for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран | |
− | + | { | |
− | + | std::cout << B[i] << " "; | |
− | + | } | |
− | + | } | |
− | + | void Func::operator *(Func D) // перегрузка оператора '*' | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | < | ||
− | < | ||
− | [ | ||
− | < | ||
− | |||
− | < | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | UmnFunc(D); // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1*f2 будет работать аналогично записи f1.UmnFunc(f2) | |
− | + | } | |
− | + | void Func::DelFunc (Func D) // функция, линейно делящая значения первой функци на значения второй функции | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | std::ofstream out("zap.txt"); // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы | |
− | + | for(int i=0; i<=D.j; ++i) // создание цикла, повторяющегося (D.j+1) раз | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | for (int | ||
{ | { | ||
− | + | B[i]=B[i]/D.A[i]; // деление значений первой функций на значенийя второй для одного и того же значения переменной | |
} | } | ||
− | + | for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий | |
− | |||
− | |||
− | |||
− | |||
− | for(int i=0; i<=j; ++i) // создание цикла, | ||
{ | { | ||
− | + | out << B[i] << '\n'; // запись значений, полученных в предыдущем цикле, в файл | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | out << B[i] << '\n'; | ||
} | } | ||
out.close(); // закрытие файла после записи в него значений | out.close(); // закрытие файла после записи в него значений | ||
D.Viv(); | D.Viv(); | ||
std::cout << std::endl << "y "; | std::cout << std::endl << "y "; | ||
− | for (int i=0; i<=D.j; ++i) | + | for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран |
{ | { | ||
std::cout << B[i] << " "; | std::cout << B[i] << " "; | ||
} | } | ||
} | } | ||
− | void Func::operator | + | void Func::operator /(Func D) // перегрузка оператора '/' |
{ | { | ||
− | + | DelFunc(D); // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1/f2 будет работать аналогично записи f1.DelFunc(f2) | |
} | } | ||
− | void Func:: | + | void Func::In (Func D) // функция, интерполирующая первую функцию по второй |
{ | { | ||
− | std:: | + | double l=c/D.c; // создаем переменную, которой присваиваем значение, обозначающее, во сколько раз один шаг больше другого |
− | for(int i=0; i<= | + | c=D.c; // приводим больший шаг к меньшему значению |
+ | z=D.j+1; // ранее созданной переменной присваиваем значение, равное количеству элементов плюс один | ||
+ | int p=l; // создаем целочисленную переменную, равную переменной l | ||
+ | B = new double [D.j+2]; // создание массива с количеством элементов D.j+2 | ||
+ | D.Viv(); std::cout << std::endl << "y "; | ||
+ | B[0]=A[0]; std::cerr << B[0] << " "; // присваиваем первому элементу нового массива значение первого элемента старого массива и выводим его на экран | ||
+ | int k=0; // создаем вспомогательную целочисленную переменную | ||
+ | for (int i=0; i<=j; i+=p) // создаем цикл, рассчитанный на j повторов через p | ||
{ | { | ||
− | + | for (int m=1; m<p; ++m) // создание цикла, выссчитывавшего промежуточное значение | |
− | + | {B[i+m]=((A[k]+A[k+1])/p)*(l-m); std::cerr << B[i+m] << " ";} // присваиваем (i+m)-ому элементу значение, выссчитанного по формуле через заданные изначально значения и вывод егона экран | |
− | + | B[i+p]=A[k+1]; // присваивание значению (i+p)-ого элемента нового массива значения (k+1)-ого элемента старого массива | |
− | + | std::cerr << B[i+p] << " "; // вывод высчитанного выше значения на экран | |
− | + | k=k+1; // увеличение k на единицу | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | std:: | ||
} | } | ||
} | } | ||
− | void Func:: | + | void Func::App () // функция, аппроксимирующая полученную в результате сложения/вычитания/деления/умножения двух функций функцию |
{ | { | ||
− | + | double d=0,e=0,f=0,g=0; // создание переменных | |
− | } | + | double k=0,l=0; // создание переменных |
− | + | for (int i=0; i<z; ++i) // цикл, который высчитывает сумму произведений зависимой и независимой переменных | |
− | { | + | {d=i*B[i]+d;} |
− | + | for (int i=0; i<z; ++i) // цикл, который высчитывает сумму всех значений функции | |
− | for(int i=0; i< | + | {e=B[i]+e;} |
+ | for (int i=0; i<z; ++i) // цикл, высчитывающий сумму всех аргументов функции | ||
+ | {f=i+f;} | ||
+ | for (int i=0; i<z; ++i) // цикл, высчитывающий сумму квадратов всех аргументов функции | ||
+ | {g=i*i+g;} | ||
+ | k=(z*d-f*e)/(z*g-f*f); // расчет углового коэффициента прямой | ||
+ | l=(e-k*f)/z; // расчет свободного коэффициента прямой | ||
+ | std::cout << "y=" << k << "x+" << l; // вывод уравнения полученной прямой на экран | ||
+ | std::ofstream out("ap.txt"); // запись полученного уравнения в файл | ||
{ | { | ||
− | + | out << "y=" << k << "x+" << l; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | out.close(); | ||
} | } | ||
− | + | ||
− | + | ||
− | + | ||
− | + | #include <iostream> | |
− | + | #include <fstream> | |
+ | #include "Func.h" | ||
+ | |||
+ | using namespace std; | ||
+ | double m,n,o, m1, n1, o1; | ||
+ | int a; | ||
+ | char b; | ||
+ | |||
+ | int main() | ||
{ | { | ||
− | + | cout << "Enter the beginning, the end and the step of a function." << endl; // ввод опорных значений первой функции: начало, конец, шаг; | |
− | + | cin >> m >> n >> o; // считывание значений | |
− | + | cout << "Enter the beginning, the end and the step of another function." << endl; // ввод опорных значений второй функции: начало, конец, шаг; | |
− | + | cin >> m1 >> n1 >> o1; // считывание значений | |
− | + | Func F(m,n,o); // создание объекта класса Func, определяющий первую функцию | |
− | + | cout << "The first function is" << endl; F.Viv(); cout << endl << "y "; | |
− | { | + | F.DefFunc(); // определение первой функции через создание массива с ее значениями |
− | + | cout << endl; | |
− | } | + | Func F1(m1,n1,o1); // создание объекта класса Func, определяющий вторую функцию |
− | + | cout << "The second function is" << endl; F1.Viv(); cout << endl << "y "; | |
− | + | F1.DefFunc(); // определение второй функции через создание массива с ее значениями | |
− | + | cout << endl; | |
− | + | cout << "As two functions have different steps, we made the interpolation of the first function." << endl; | |
− | { | + | F.In(F1); // линейная интерполяция первой функции по второй |
− | + | cout << endl; | |
− | } | + | cout << "What do you want to do with these functions?" << '\n' << "Enter 1 to sum them;" << '\n' << "Enter 2 to subtract the second from the first;" << '\n' << "Enter 3 to multiply them;" << '\n' << "Enter 4 to divide first by second" << endl; |
+ | cin >> a; | ||
+ | if (a==1) | ||
+ | {cout << "Function 1 + function 2 =" << '\n'; F+F1;} // сложение двух функций с одинаковым шагом и интервалом | ||
+ | else if (a==2) | ||
+ | {cout << "Function 1 - function 2 =" << '\n'; F-F1;} // вычитание двух функций с одинаковым шагом и интервалом | ||
+ | else if (a==3) | ||
+ | {cout << "Function 1 * function 2 =" << '\n'; F*F1;} // умножение двух функций с одинаковым шагом и интервалом | ||
+ | else if (a==4) | ||
+ | {cout << "Function 1 / function 2 =" << '\n'; F/F1;} // деление двух функций с одинаковым шагом и интервалом | ||
+ | cout << endl; | ||
+ | cout << "Enter 5 to do the approximation of the result function" << endl; // пользователь сам выбирает, выполнять ли аппроксимацию; | ||
+ | cout << "Otherwise enter 6 to quit" << endl; | ||
+ | cin >> a; | ||
+ | if (a==5) | ||
+ | {cout << "Appromaximation:" << endl; | ||
+ | F.App();} // аппроксимация | ||
+ | return 0; | ||
} | } | ||
− | + | ||
− | + | </syntaxhighlight> | |
− | + | </div> | |
− | + | ||
− | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > | |
− | + | '''[[Савельева Ольга]]''' | |
− | + | ||
− | + | '''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения. | |
− | + | <div class="mw-collapsible-content"> | |
− | + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | |
− | + | #include <stdio.h> | |
− | + | #include <stdlib.h> | |
− | + | //Бибилотека необходимая для возможности включения русского языка в консоли | |
− | + | #include <locale.h> | |
− | + | ||
− | + | class fun | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | /* | |
− | + | fx - массив с дискретными значениями функции | |
− | + | a - начало отрезка определения функции | |
− | + | b - конец отрезка определения функции | |
− | + | dx - шаг | |
− | + | */ | |
− | + | double *fx, a, b, dx; | |
− | + | //Чтобы очусть ошибки округления в вещественных числах при сравнениях используется константа eps. | |
− | + | //К примеру два вещественных числа x и y сравниваются не так x>=y, а так x-y>=-eps. | |
− | + | const double eps = 1e-10; //1e-10 это тоже самое что 0.0000000001 | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | public: | ||
+ | //Коструктор по умолчанию | ||
+ | fun(); | ||
+ | //Конструктор копирования | ||
+ | fun(fun &tmp); | ||
+ | //Деструктор | ||
+ | ~fun(); | ||
+ | //Перегруженные операторы. Ключевое слово const в конце означает, что объект от которого вызвается метод не изменяется | ||
+ | const fun operator+(const fun& right) const; | ||
+ | const fun operator-(const fun& right) const; | ||
+ | const fun operator*(const fun& right) const; | ||
+ | const fun operator/(const fun& right) const; | ||
+ | const fun& operator=(const fun& right); | ||
− | + | //Метод считывания из файла | |
− | + | void readFile(const char *path); | |
− | + | //Метод вывода в файл | |
+ | void writeFile(const char *path); | ||
− | + | //Метод изменения шага | |
− | double | + | void changeDx(double newDx); |
− | + | //Метод вычисления значения в заданной точке | |
− | + | double getX(double x1); | |
+ | }; | ||
+ | |||
+ | //В конструкторе по умолчанию все просто. | ||
+ | fun::fun() | ||
+ | { | ||
+ | a = b = dx = 0; | ||
+ | fx = NULL; | ||
+ | } | ||
− | + | //Конструктор копирования | |
+ | fun::fun(fun &tmp) | ||
{ | { | ||
− | + | int i, n; | |
− | + | //Копирование свойств объекта tmp в текущий объект | |
− | + | a = tmp.a; | |
− | + | b = tmp.b; | |
− | + | dx = tmp.dx; | |
− | + | //Вычисление количества дискретных значений | |
− | + | n = (b - a) / dx + 1; | |
− | + | //Выделение необходимой памяти для хранения дискретных значений | |
− | + | fx = new double[n]; | |
− | + | //Копирование дискретных значений объекта tmp в текущий объект | |
− | + | for (i = 0; i<n; ++i) | |
− | + | fx[i] = tmp.fx[i]; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | //Деструктор | |
− | + | fun::~fun() | |
− | + | { | |
− | + | //Освобождение памяти выделенной для массива дискретных значений | |
− | + | if (fx != NULL) delete[] fx; | |
− | + | } | |
− | + | //Оператор сложения. | |
− | + | const fun fun::operator+(const fun& right) const | |
− | + | { | |
− | + | //Создание результирующего объекта | |
− | + | fun result; | |
− | // | + | int i, n; |
− | + | //Копирование свойств в результирующий объект | |
+ | result.dx = dx; | ||
+ | result.a = a; | ||
+ | result.b = b; | ||
+ | //Вычисление количества дискретных значений | ||
+ | n = (b - a) / dx + 1; | ||
+ | //Выделение необходимой памяти для хранения дискретных значений | ||
+ | result.fx = new double[n]; | ||
+ | //Вычисление дискретных значений результирующего объекта | ||
+ | for (i = 0; i<n; ++i) | ||
+ | result.fx[i] = fx[i] + right.fx[i]; | ||
+ | |||
+ | //Возвращение результата | ||
+ | return result; | ||
+ | } | ||
− | + | //Этот оператор аналогичен оператору сложение | |
+ | const fun fun::operator-(const fun& right) const | ||
{ | { | ||
− | + | fun result; | |
− | + | int i, n; | |
− | a | + | result.dx = dx; |
− | b | + | result.a = a; |
− | + | result.b = b; | |
− | + | n = (b - a) / dx + 1; | |
− | + | result.fx = new double[n]; | |
− | + | for (i = 0; i<n; ++i) | |
− | + | result.fx[i] = fx[i] - right.fx[i]; | |
− | |||
− | + | return result; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | //Этот оператор аналогичен оператору сложение | |
− | + | const fun fun::operator*(const fun& right) const | |
− | + | { | |
− | + | fun result; | |
− | + | int i, n; | |
− | + | result.dx = dx; | |
− | + | result.a = a; | |
− | + | result.b = b; | |
− | + | n = (b - a) / dx + 1; | |
− | + | result.fx = new double[n]; | |
− | + | for (i = 0; i<n; ++i) | |
+ | result.fx[i] = fx[i] * right.fx[i]; | ||
− | + | return result; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | // | + | //Этот оператор аналогичен оператору сложение |
− | fun:: | + | const fun fun::operator/(const fun& right) const |
{ | { | ||
+ | fun result; | ||
int i, n; | int i, n; | ||
− | + | result.dx = dx; | |
− | a = | + | result.a = a; |
− | b = | + | result.b = b; |
− | |||
− | |||
n = (b - a) / dx + 1; | n = (b - a) / dx + 1; | ||
− | + | result.fx = new double[n]; | |
− | |||
− | |||
for (i = 0; i<n; ++i) | for (i = 0; i<n; ++i) | ||
− | fx[i] = | + | result.fx[i] = fx[i] / right.fx[i]; |
− | |||
− | + | return result; | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | //Оператор | + | |
− | const fun fun::operator | + | //Оператор присваивания |
+ | const fun& fun::operator=(const fun& right) | ||
{ | { | ||
− | // | + | //Проверка на самоприсваивание |
− | + | if (this == &right) | |
+ | //Возвращение в качестве результата текущий объект | ||
+ | return *this; | ||
+ | |||
+ | |||
int i, n; | int i, n; | ||
− | // | + | //Присваивание свойств объекта right текущему объекту |
− | + | a = right.a; | |
− | + | b = right.b; | |
− | + | dx = right.dx; | |
//Вычисление количества дискретных значений | //Вычисление количества дискретных значений | ||
n = (b - a) / dx + 1; | n = (b - a) / dx + 1; | ||
+ | //Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них | ||
+ | if (fx != NULL) delete[] fx; | ||
//Выделение необходимой памяти для хранения дискретных значений | //Выделение необходимой памяти для хранения дискретных значений | ||
− | + | fx = new double[n]; | |
− | // | + | |
+ | //Копирование дискретных значений объекта right в текущий объект | ||
for (i = 0; i<n; ++i) | for (i = 0; i<n; ++i) | ||
− | + | fx[i] = right.fx[i]; | |
− | //Возвращение результата | + | //Возвращение в качестве результата текущий объект |
− | return | + | return *this; |
} | } | ||
− | // | + | /* |
− | + | Метод считывания из файла | |
+ | path - путь к файлу из которого считывать | ||
+ | */ | ||
+ | |||
+ | void fun::readFile(const char *path) | ||
{ | { | ||
− | + | //Открытие файла для считывания | |
+ | FILE *in = fopen(path, "r"); | ||
int i, n; | int i, n; | ||
− | + | //Считывание границ отрезка и шага из файла | |
− | + | fscanf(in, "%lf%lf%lf", &a, &b, &dx); | |
− | + | //Вычисление количества дискретных значений | |
n = (b - a) / dx + 1; | n = (b - a) / dx + 1; | ||
− | + | //Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них | |
− | for (i = 0; i<n; ++i) | + | if (fx != NULL) delete[] fx; |
− | + | //Выделение необходимой памяти для хранения дискретных значений | |
− | + | fx = new double[n]; | |
− | + | //Считывание дискретных значений из файла | |
+ | for (i = 0; i<n; ++i) fscanf(in, "%lf", &fx[i]); | ||
+ | //Закрытие файла | ||
+ | fclose(in); | ||
} | } | ||
− | / | + | /* |
− | + | Метод вывода в файл | |
− | + | path - путь к файлу в который нужно вывести | |
− | + | */ | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | void fun::writeFile(const char *path) | |
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | + | //Открытие файла для вывода | |
+ | FILE *out = fopen(path, "w"); | ||
int i, n; | int i, n; | ||
− | + | double x = a; | |
− | + | //Вычисление количества дискретных значений | |
− | |||
n = (b - a) / dx + 1; | n = (b - a) / dx + 1; | ||
− | + | //Вывод информации о отрезке и шаге в файл | |
− | for (i = 0; i<n; ++i) | + | fprintf(out, "[%.5lf, %.5lf] dx=%.5lf\n", a, b, dx); |
− | + | //Последовательный вывод пары (точка, значение в точке) в файл | |
− | + | for (i = 0; i<n; ++i, x += dx) | |
− | + | fprintf(out, "x=%.5lf f(x)=%.5lf\n", x, fx[i]); | |
+ | //Закрытие файла | ||
+ | fclose(out); | ||
} | } | ||
− | // | + | /* |
− | + | Метод изменения величины шага | |
+ | */ | ||
+ | void fun::changeDx(double newDx) | ||
{ | { | ||
− | + | int i, j, n, newN; | |
− | + | double *newFx, x, newX, x1, y1, x2, y2, K, B; | |
− | + | //Вычисление количества старых дискретных значений | |
− | |||
− | |||
− | |||
− | int i, n; | ||
− | |||
− | |||
− | |||
− | |||
− | //Вычисление количества дискретных значений | ||
n = (b - a) / dx + 1; | n = (b - a) / dx + 1; | ||
− | // | + | //Вычисление количества новых дискретных значений |
− | + | newN = (b - a) / newDx + 1; | |
− | //Выделение | + | //Выделение памяти под новые дискретные значения |
− | + | newFx = new double[newN]; | |
− | + | //Определение первой точки в которой вычисляется новое дискретное значение | |
− | // | + | newX = a; |
− | for ( | + | //Переменная которая бежит по старым дискретным значениям |
− | + | i = 0; | |
− | + | //Определение первой точки в которой вычисляется старое дискретное значение | |
− | // | + | x = a; |
− | + | //Цикл для формирования новых дискретных значений | |
+ | for (j = 0; j<newN; ++j, newX += newDx) | ||
+ | { | ||
+ | //В цикле находим отрезок где лежит точка в которой нужно вычислить новое дискретное значение | ||
+ | for (; i<n - 1; ++i, x += dx) | ||
+ | //Если без eps, то сравнения такие: x<=newX<=x+dx | ||
+ | if ((newX - x>-eps) && ((x+dx) - newX>-eps)) | ||
+ | { | ||
+ | //Линейная интерполяция | ||
+ | x1 = x; | ||
+ | x2 = x + dx; | ||
+ | y1 = fx[i]; | ||
+ | y2 = fx[i + 1]; | ||
+ | K = (y2 - y1) / (x2 - x1); | ||
+ | B = (y2*x1 - y1*x2) / (x1 - x2); | ||
+ | //Вычисления значения в точке с помощью линейной интерполяции | ||
+ | newFx[j] = newX*K + B; | ||
+ | //Выход из цикла по i | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | //Смена величины шага на новый | ||
+ | dx = newDx; | ||
+ | //Удаление старых дискретных значений | ||
+ | delete[] fx; | ||
+ | //Присвоение текущему объекту новых дискретных значений | ||
+ | fx = newFx; | ||
} | } | ||
/* | /* | ||
− | Метод | + | Метод вычисляет значение в точке xAns с помощью линейной интерполяции. |
− | |||
*/ | */ | ||
− | + | double fun::getX(double xAns) | |
− | |||
{ | { | ||
− | |||
− | |||
int i, n; | int i, n; | ||
− | + | double x, x1, y1, x2, y2, K, B; | |
− | + | x = a; | |
//Вычисление количества дискретных значений | //Вычисление количества дискретных значений | ||
n = (b - a) / dx + 1; | n = (b - a) / dx + 1; | ||
− | // | + | //Ищем отрезок в котором лежит точка xAns |
− | + | for (i = 0; i<n - 1; ++i, x += dx) | |
− | + | { | |
− | + | //Если без eps, то сравнения такие: x<=newX<=x+dx | |
− | + | if (((x+dx) - xAns>-eps) && (xAns - x>-eps)) | |
− | + | { | |
− | + | //Линейная интерполяция | |
− | + | x1 = x; | |
+ | x2 = x + dx; | ||
+ | y1 = fx[i]; | ||
+ | y2 = fx[i + 1]; | ||
+ | K = (y2 - y1) / (x2 - x1); | ||
+ | B = (y2*x1 - y1*x2) / (x1 - x2); | ||
+ | //Вычисления значения функции в заданной точке с помощью линейной интерполяции | ||
+ | return K*xAns + B; | ||
+ | } | ||
+ | } | ||
} | } | ||
− | + | int main() | |
− | |||
− | |||
− | |||
− | |||
− | |||
{ | { | ||
− | // | + | //Включение поддержки русского языка в консоли |
− | + | setlocale(LC_ALL, "Russian"); | |
− | + | //Объявление трех переменных типа fun | |
− | + | fun a, b, c; | |
− | // | + | //Считывания первых дискретных значений из файла inputA.txt |
− | + | a.readFile("inputA.txt"); | |
− | // | + | //Считывания вторых дискретных значений из файла inputB.txt |
− | + | b.readFile("inputB.txt"); | |
− | // | + | |
− | + | //Первая функция | |
− | + | a.writeFile("outputA.txt"); | |
− | // | + | //Вторая функция |
− | + | b.writeFile("outputB.txt"); | |
− | + | ||
+ | c = a + b; | ||
+ | //Результат сложения двух функций | ||
+ | c.writeFile("outputAaddB.txt"); | ||
+ | |||
− | / | + | c = a - b; |
− | + | //Результат вычитания второй функции из первой | |
− | + | c.writeFile("outputAsubB.txt"); | |
− | + | ||
− | + | c = a*b; | |
− | + | //Результат умножения двух функций | |
− | + | c.writeFile("outputAmultiB.txt"); | |
− | // | + | |
− | + | c = a / b; | |
− | + | //Результат деления первой функции на вторую | |
− | + | c.writeFile("outputAdivB.txt"); | |
− | // | + | |
− | + | //У первой функции изменили шаг на 0.5 | |
− | // | + | a.changeDx(0.5); |
− | + | //Вывели её дискретные значения | |
− | + | a.writeFile("outputChangeDx.txt"); | |
− | + | ||
− | // | + | //Функция, которая аппроксимирует её кусочно линейная. |
− | + | //Для примера нашли значение аппроксимируещей функции в точке не совпадающей с дискретными значениями. | |
− | // | + | printf("Значение в точке 1.8 первой функции %.5lf\n", a.getX(1.8)); |
− | + | ||
− | + | //Нужно чтобы окно консоли автоматически не закрылось | |
− | + | system("pause"); | |
− | + | return 0; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | // | ||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Скачать можно [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8.zip здесь] | |
− | + | ||
− | + | '''[[Степанянц Степан]]''' | |
− | + | ||
+ | '''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.Данныеберутся из файла. | ||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="cpp" line start="1" enclose="div"> | ||
+ | |||
+ | |||
+ | #include <iostream> | ||
+ | #include <vector> | ||
+ | #include <math.h> | ||
+ | #include <fstream> | ||
+ | #include <stdio.h> | ||
+ | #include <string> | ||
+ | #include <time.h> | ||
− | + | using namespace std; | |
− | |||
− | |||
+ | class func { | ||
+ | vector <double> vals; | ||
+ | double a, b, step, sz; | ||
− | + | public: | |
− | + | func (string fil) { //конструктор для ввода функции из файла | |
− | + | ifstream f(fil.c_str()); | |
− | + | double a, b, step, y; | |
− | + | f >> a >> b >> step; //вводим основные значения из файла | |
− | + | this->step = step; | |
− | + | this->sz = (int)((b - a) / step + 1); //считаем размер | |
− | + | this->a = a, this->b = b; | |
− | + | for (int i = 0; i < this->sz; i++) { | |
− | + | f >> y; | |
− | + | this->vals.push_back(y); //считываем и записываем значения из файла | |
− | + | } | |
− | + | f.close(); | |
− | + | } | |
− | + | func () {} //еще один конструктор | |
− | + | func operator + (func a) { // эта и ближайшие четыре метода -- калькулятор функций | |
− | + | func f = *new func(); //создаем новый экземпляр класса, ответ | |
− | + | for (int i = 0; i < sz; i++) { | |
− | + | f.vals.push_back(this->vals[i] + a.vals[i]); // складываем покоординатно | |
− | + | } | |
− | + | f.step = a.step; // копируем все значения в ответ (возможно, это можно сделать гораздо проще и не писать 4*4 строк но почему-то ничего умнее я не придумал) | |
− | + | f.a = a.a; | |
− | + | f.b = a.b; | |
− | + | f.sz = a.sz; | |
− | } | + | return f; |
− | + | } | |
− | </ | + | func operator - (func a) { |
− | + | func f = *new func(); | |
− | + | for (int i = 0; i < a.sz; i++) { | |
− | + | f.vals.push_back(this->vals[i] - a.vals[i]); | |
− | + | } | |
+ | f.step = a.step; | ||
+ | f.a = a.a; | ||
+ | f.b = a.b; | ||
+ | f.sz = a.sz; | ||
+ | return f; | ||
+ | } | ||
+ | func operator * (func a) { | ||
+ | func f = *new func(); | ||
+ | for (int i = 0; i < a.sz; i++) { | ||
+ | f.vals.push_back(this->vals[i] * a.vals[i]); | ||
+ | } | ||
+ | f.step = a.step; | ||
+ | f.a = a.a; | ||
+ | f.b = a.b; | ||
+ | f.sz = a.sz; | ||
+ | return f; | ||
+ | } | ||
+ | func operator / (func a) { | ||
+ | func f = *new func(); | ||
+ | for (int i = 0; i < a.sz; i++) { | ||
+ | f.vals.push_back(this->vals[i] / a.vals[i]); | ||
+ | } | ||
+ | f.step = a.step; | ||
+ | f.a = a.a; | ||
+ | f.b = a.b; | ||
+ | f.sz = a.sz; | ||
+ | return f; | ||
+ | } | ||
− | + | pair<double, double> approx() { //аппроксимация. это все из наших лаб по физике, тут сплошная математика, никакого программирования | |
− | + | double mid = 0; | |
− | + | for (int i = 0; i < this->sz; i++) { | |
− | + | mid += this->a + i * this->step; | |
− | + | } | |
− | + | mid /= this->sz; | |
− | + | double d = 0; | |
− | + | for (int i = 0; i < this->sz; i++) { | |
− | + | d += pow((this->a + i * this->step - mid), 2.); | |
− | + | } | |
− | + | double a = 0; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | this-> | ||
− | this->sz = ( | ||
− | |||
for (int i = 0; i < this->sz; i++) { | for (int i = 0; i < this->sz; i++) { | ||
− | + | a += (this->a + i * this->step - mid) * this->vals[i]; | |
− | |||
} | } | ||
− | + | a /= d; | |
+ | double midy = 0; | ||
+ | for (int i = 0; i < this->sz; i++) { | ||
+ | midy += this->vals[i]; | ||
+ | } | ||
+ | midy /= this->sz; | ||
+ | double c = midy - a * mid; | ||
+ | return {a, c}; //{x,y} возвращает пару (на самом деле не пару а просто какой-нибудь объект) с первым значением x и вторым y | ||
} | } | ||
− | + | ||
− | func | + | func inter(double step) { |
− | func f = *new func(); // | + | func f = *new func(); //ответ |
− | for (int i = 0; i < sz; i++) { | + | double curr2, curr1; |
− | f.vals.push_back(this->vals[ | + | int j = 0; |
+ | f.a = this->a, f.b = this->b, f.step = step, f.sz = (int)((b - a) / step + 1); | ||
+ | for (int i = 0; i < f.sz; i++) { | ||
+ | curr2 = a + i * step; | ||
+ | curr1 = a + j * this->step; | ||
+ | while (curr1 + this->step <= curr2) { | ||
+ | j++, curr1 += this->step; | ||
+ | } | ||
+ | if (curr1 == curr2) { | ||
+ | f.vals.push_back(this->vals[j]); | ||
+ | continue; | ||
+ | } | ||
+ | f.vals.push_back((this->vals[j + 1] - this->vals[j]) * (curr2 - curr1) / this->step + this->vals[j]);//я хз, тут видимо какая-то математика | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
return f; | return f; | ||
− | } | + | } |
− | + | void write(string fil) { //запись. чтобы записать не в файл, а в консоль вывести, надо передать "-1" | |
− | + | ofstream f(fil.c_str()); | |
− | + | if (fil != "-1") { | |
− | f | + | f << this->a << ' ' << this->b << ' ' << this->step << '\n'; |
} | } | ||
− | + | else | |
− | + | cout << this->a << ' ' << this->b << ' ' << this->step << '\n'; | |
− | + | for (int i = 0; i < sz; i++) { | |
− | + | if (fil != "-1") | |
− | + | f << this->vals[i] << '\n'; | |
− | + | else | |
− | + | cout << this->vals[i] << '\n'; | |
− | |||
− | for (int i = 0; i < | ||
− | f | ||
} | } | ||
− | f. | + | f.close(); |
− | + | ||
− | |||
− | |||
− | |||
} | } | ||
− | + | }; | |
− | + | ||
− | + | int main() { | |
− | + | string fil; | |
− | + | cout << "Input the file name with the function values\n"; | |
− | + | cin >> fil; | |
− | + | func f = *new func(fil); | |
− | + | int a; | |
− | + | char ch; | |
− | + | double st; | |
− | + | while (true) { | |
− | + | cout << "what do you want to do?\n1-math operation\n2-interpolation\n3-approximation\n4-write to file\n5-read values from file\n6-quit\n"; | |
− | + | cin >> a; | |
− | + | if (a == 4) { | |
− | + | cout << "input file name to write to\n"; | |
− | + | cin >> fil; | |
+ | f.write(fil); | ||
} | } | ||
− | + | if (a == 3) { | |
− | + | auto t = f.approx(); | |
− | + | cout << "Approximate line equation is y = " << t.first << " * x + " << t.second << '\n'; | |
− | |||
} | } | ||
− | + | if (a == 2) { | |
− | + | cout << "input step to interpolate\n"; | |
− | + | cin >> st; | |
+ | f = f.inter(st); | ||
} | } | ||
− | a | + | if (a == 1) { |
− | + | cout << "input arithmetic operator and file name with the second function values\n"; | |
− | + | cin >> ch >> fil; | |
− | + | if (ch == '+') f = f + func(fil); | |
+ | if (ch == '-') f = f - func(fil); | ||
+ | if (ch == '*') f = f * func(fil); | ||
+ | if (ch == '/') f = f / func(fil); | ||
} | } | ||
− | + | if (a == 5) { | |
− | + | cout << "Input the file name with the function values\n"; | |
− | + | cin >> fil; | |
− | + | f = *new func(fil); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | return | + | if (a == 6) |
+ | return 0; | ||
} | } | ||
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | '''[[Козловская Анна]]''' | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | '''Описание программы''': программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл. | ||
− | + | '''Пояснения к алгоритму''': Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Скачать можно [http://tm.spbstu.ru/File:project1.rar тут]. | |
− | |||
− |