Редактирование: Информатика: Функции

Перейти к: навигация, поиск

Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
'''[[Абрамов Игорь]]'''
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
  
'''Алгоритм''': функции хранятся в программе как массив точек, заданных с определённым шагом по X на заданном отрезке. Вводить значения функции в программу можно двумя способами: с помощью математических функций из стандартных библиотек, указывая начало и конец отрезка, а также шаг, с которым определена функция, и считывая координаты точек из файла, предварительно считав их количество. Далее с любыми функциями можно производить следующие действия и их комбинации: сложение, вычитание, кубическая интерполяция и линейная аппроксимация. При этом результат каждого из этих действий - новая функция, с которой можно продолжать работу. Функции можно выводить на экран с помощью средств графической библиотеки OpenGL, а также печатать её значения в файл.
 
  
'''Инструкция''': пользователь вводит необходимые действия с функциями в функции Display. На данный момент при запуске программы можно увидеть пример её работы: первая функция считывается из файла, интерполируется и выводится на экран. Затем вторая функция вводится из библиотеки math.h интерполируется и выводится на экран. Затем функции суммируются, интерполируются и выводятся на экран. [[:File:Func_Abramov.rar]]
+
'''[[Лебедев Станислав]]'''
  
Ссылка на скачивание: [http://tm.spbstu.ru/File:Func_Abramov.rar]
+
'''Описание программы''': программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.
 +
 
 +
'''Пояснения к алгоритму''':
 +
#  Прочитанные из файла функции нужно отсортировать.
 +
#  Найти совместную область определения, то есть, найти множество пересечения областей определения функций, над которыми совершается операция.
 +
#  Создать третью функцию, со следующими свойствами : область определения состоит только из точек, принадлежащих совместной области определения, каждая точка области значений является результатом нужной операции над точкой области значений одной из функций и, либо интерполированной точкой по другой функции, либо, если есть возможность, точным значением из ее области значений.
 +
 
 +
Скачать можно  [http://tm.spbstu.ru/Файл:Функции.rar тут].
  
'''[[Андреева Полина]]'''
 
  
'''Инструкция к программе:''' пользователь должен ввести начало, конец и шаг. Создается две функции. Затем на экране появляется один из знаков арифметических действий. Пользователь выбирает один из знаков. Создается третья функция. Пользователь вводит второй шаг. Функция интерполируется по этому новому шагу, а затем аппроксимируется.
 
'''Краткое описание алгоритма :''' в классе создается две функции(с помощью массивов). Так же в классе есть такие методы: перегрузка арифм операций, интерполяция, аппроксимация, вывод массивов на экран и их сохранение в файл. Сначала создается два массива для функций. Затем  с помощью перегрузки эти два массива складываются/умножаются/делятся/вычитаются и записываются опять в этот массив. В методе перегрузки сразу вызывается интерполяция и аппроксимация.
 
[http://tm.spbstu.ru/Файл:Function.rar Программа]
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
 
<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>
#include "math.h"
+
 
 
using namespace std;
 
using namespace std;
class func
+
 
 +
double base(double x)                                        //базовая функция ( если задавать через шаг и начальный х
 
{
 
{
private:
+
     return x;
    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);///так как количество это целое число, то округляем
 
  
     }
+
struct ap                                                  //две одинаковые структуры это нехорошо,коненчо,но зато наглядно...
 +
{
 +
     double k,b;
 +
};
  
    void massiv1() ///создание первой функции х^3
+
struct fun                                                  //один столбик в таблице функции
    {
+
{
        mass=new double[AmountInt];
+
    double x,y;
        for (int l=0; l<AmountInt; l++)
+
};
        {
+
 
            mass[l] =pow((l*Step+Begin),3);
+
struct sf                                                  //структура нужная, для возражеия значений из функции "prepare" класса F
        }
+
{
        cout << "y=x^3 \n";
+
    int i1,i2,e1,e2;
    }
+
    double glength, gfirstx, glastx;
    void massiv2() ///создание второй функции sin(x)
+
};
    {
+
 
        mass=new double[AmountInt];
+
double intr(double x1,double x2,double x,double y1,double y2) // линенейная интерполяция
        for (int l=0; l<AmountInt; l++)
+
{
        {
+
    return ( ((x-x1)/(x2-x1)) * (y2-y1) + y1 );
            mass[l] =sin(l*Step+Begin);
+
}
        }
 
        cout << "y=sin(x) \n";
 
    }
 
  
     void interpolation(double __Begin, double __End, double __Step)
+
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;
         double NewAmount=((__End-__Begin)/__Step) + 1;///количество точек для нового шага
+
        x   += b[i].x;
        int NewAmountInt=static_cast<int>(NewAmount);
+
        y  += b[i].y;
        for (int i=0; i<NewAmountInt; i++)///i-это точки функции с новыми шагами
+
        sqx += b[i].x*b[i].x;
        {
+
         xsq += b[i].x;
            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";
 
 
     }
 
     }
 +
    xsq *= xsq;
  
     void approximation(double __Begin, double __End, double __Step)
+
     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 вычисляется по базовой функции
 
     {
 
     {
         double SumXMass=0;///это сумма умножений x на значение функции в этом x для всех значений
+
         if (l >= 0)
        double SumX=0;///сумма всех значений x
+
          a = new fun [l];
         double SumMass=0;///сумма всех значений функции в точках x
+
         firstx = f;
         double SumXX=0;///сумма всех квадратов значений x
+
         length = l;
         mass1 = new double[AmountInt];
+
         step = s;
         double x;
+
         lastx = firstx+(length - 1)*step;
        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++)
+
         for (int i = 0;i < length; i ++)
 
         {
 
         {
             mass1[i] = a*(i*__Step+__Begin)+b;///такие значения принимает апроксимация
+
             a[i].y = base(firstx + i*step);
 +
            a[i].x = firstx + i*step;
 
         }
 
         }
        delete[] mass;
 
        mass=mass1;
 
        output();///вывод на экран
 
        SaveFile("approximation.txt");///сохранение в файл
 
        cout<<"end of appox";
 
  
 
     }
 
     }
  
     func operator+( func f)///перегрузка оператора +
+
     F (fun b[],int l)                                   //конструктор для создания фунции с уже известными областями определния и значений
 
     {
 
     {
         func newmass(Begin, End, Step);
+
         length = l;
         masss=new double[AmountInt];///новая функция равная сумме данныйх функций
+
         a = new fun [l];
         for (int i=0; i<AmountInt; i++)
+
         for (int i = 0; i < l;i++)
        {
+
             a[i] = b[i];
             masss[i] = mass[i] + f.mass[i];
+
 
        }
+
         for (int i = 0; i < l;i++)
         delete [] mass;
+
            for (int j = 0; j < (l - 1); j++)
        mass=masss;
+
                if (a[j].x > a[j + 1].x)
        output();///вывод на экран резултата
+
                {
        SaveFile("f3.txt");///сохранение в файл
+
                    fun tmp = a[j];
        cout<<"enter new step";
+
                    a[j] = a[j + 1];
        cin>>Step2;
+
                    a[j + 1] = a[j];
        cout<<"interpolation: ";
+
                }
        interpolation(Begin,End,Step2);///интерполяция
 
        cout<<" approximation: ";
 
        approximation(Begin,End,Step2);///аппроксимация
 
        return newmass;
 
  
 +
        firstx = a[0].x;
 +
        lastx = a[length - 1].x;
 
     }
 
     }
  
     func operator-( func f)
+
     void addpar (double k, double b, int l, fun z[] )                           //позволяет создать и заполнить переданным массивом поле объекта класса
 
     {
 
     {
         func newmass(Begin, End, Step);
+
         a = new fun [l];
        masss=new double[AmountInt];
+
         for (int i = 0; i < l; i++)
         for (int i=0; i<AmountInt; i++)
 
 
         {
 
         {
             masss[i] = mass[i] - f.mass[i];
+
             a[i].y = k*z[i].x + b;
 +
            a[i].x = z[i].x;
 
         }
 
         }
         delete [] mass;
+
         length = l;
        mass = masss;
+
    }
        output();
+
 
        SaveFile("f3.txt");
+
    double getelx(int i)                               //возращает значение из поля "х" iого элемента
        cout<<"enter new step";
+
    {
        cin>>Step2;
+
         return a[i].x;
        cout<<"interpolation: ";
 
        interpolation(Begin,End,Step2);
 
        cout<<" approximation: ";
 
        approximation(Begin,End,Step2);
 
         return newmass;
 
 
     }
 
     }
     func operator/( func f)
+
 
 +
 
 +
     double getely(int i)                               //возращает значение из поля "х" iого элемента
 
     {
 
     {
         func newmass(Begin, End, Step);
+
         return a[i].y;
        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)
+
 
 +
     int getlength()                                //возращает размер области определения функции(в точках)
 
     {
 
     {
        func newmass(Begin, End, Step);
+
         return length;
        masss=new double[AmountInt];
 
        for (int i=0; i<AmountInt; 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 FOut()                                     //выводит функцию на экран
     void output()///вывод функции на экран
 
 
     {
 
     {
         for (int i=0; i<AmountInt; i++)
+
      cout << "  x         y" << endl;
        {
+
      for (int i = 0;i < length; i ++)
            cout << "y("<<i<< ") = " << mass[i] <<endl;
+
          cout << "   " << a[i].x << "         " << a[i].y << endl;
 
+
      cout << endl;
        }
 
 
     }
 
     }
  
  
     void SaveFile(char filename[])///сохранение функции в файл
+
     int pfind(double x)const                        //возращает либо номер элемента,идущщий перед элементом, большим,чем х; в случае нахождения равного, возращает число, противоположное номеру следующего элемента(иначе может вернуться нуль,а нуль знака не имееет)
 
     {
 
     {
        std::ofstream fout(filename);
+
         for (int i = 0; i < length-1; i++ )
         for (int l=0; l<AmountInt; l++)
 
 
         {
 
         {
             fout<<l<<" "<<mass[l]<<" \n";
+
             if (((a[i].x < x) && (a[i + 1].x > x)))
         }
+
                return (i + 1);
 
+
            else
        fout.close();
+
                // чтобы иметь возможность проанализировать полученное значение функции,мы должны понимать, было найденно равное или промежуточное значение. "флагом" равных значений является знак минус,но так у нуля нет знака,то приходиться все сдвигать на 1
 +
                if (a[i].x == x)
 +
                  return -(i + 1);
 +
                else
 +
                    if (a[i + 1].x == x)
 +
                        return -(i + 2);
 +
        }
 +
//        cerr << "fail!!" << endl;
 +
         return -1;
 
     }
 
     }
};
 
  
 +
    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));
  
int main()
+
        return r;
{
+
     }
 
 
    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);///создание первой функции
+
     void ad (fun b[],int l)                                 //присвоить массиву объекта класса F значения массива b
     f1.massiv1();
+
     {
    f1.output();
+
        length = l;
    cout<<"\n ";
+
        a = new fun [l];
     f1.SaveFile("f1.txt");
+
        for (int i = 0; i < l;i++)
 +
            a[i] = b[i];
 +
        firstx = a[0].x;
 +
        lastx = a[length - 1].x;
 +
     }
  
     func f2(Begin1,End1,Step1);///создание второй функции
+
     fun *geta()                                         //получения указателя на начало массива в поле класса
    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:
+
         return a;
    {
 
         f3=f1+f2;///сумма функций
 
        break;
 
 
     }
 
     }
     case 2:
+
 
 +
     F operator +(F &x) const                              //сложение двух функций
 
     {
 
     {
         f3=f1-f2;
+
         int i1, e1, i2, e2, kk = 0;
         break;
+
         double gfirstx, glastx, glength;
    }
 
    case 3:
 
    {
 
        f3=f1/f2;
 
        break;
 
    }
 
    case 4:
 
    {
 
        f3=f1*f2;
 
        break;
 
    }
 
  
    default :
+
        if (((x.lastx < firstx) && (x.firstx < firstx)) || ((lastx < x.firstx) && (firstx < x.firstx)))
    {
+
        {
        cout<<"NOOOOO";
+
            cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
         break;
+
            F fl(-1,0,0);
    }
+
            return fl;
    };
+
        }
    return 0;
+
         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;
 +
            }
  
</syntaxhighlight>
+
        return tmp;
</div>
+
}
 
 
'''[[Анастасия Бальцер]]'''
 
  
'''Описание программы''': Программа считывает из файла значения функций и количество точек, затем с ними можно провести следующие действия: сложить, умножить, линейно интерполировать и линейно аппроксимировать. Все результаты выводятся в отдельные файлы.
+
    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;
 +
        }
  
Скачать можно  [http://tm.spbstu.ru/Файл:inter.zip тут].
+
        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];
Скачать программу можно по ссылке  [http://tm.spbstu.ru/Файл:задача_2.zip].
+
                tmp.a[j + 1] = t;
 
+
            }
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<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 ///создаем класс функции
+
        return tmp;
{
+
    }
  
private: ///объявляем тип переменных в привате
+
    F operator ^(F & x) const                                  //возведение функции слева от оператора в степень функции справа от оператора
     double *mass, *mass1, *mass2; ///*mass, *mass1, *mass2 -определение двумерного массива
+
     {
    double start, ending, step, step2, amountdouble; ///start-начало, ending-конец, step-шаг, amountdouble-количество точек (типа double)
+
        int i1, e1, i2, e2, kk = 0;
 +
        double gfirstx, glastx, glength;
  
public: ///объявляем тип переменных в паблике
+
        if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
    int amount; ///amoun-количество точек (типа int)
+
        {
 +
            cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
 +
            F fl(-1,0,0);
 +
            return fl;
 +
        }
  
functya (double _start, double _ending, double _step):start(_start),ending(_ending),step(_step) ///создаем конструктор функции с объявлением переменных
+
        sf r = prepare(x);
{
+
        F tmp(r.glength,r.gfirstx,r.glastx);
  
    amountdouble=((ending-start)/step)+1; ///подсчитываем количество точек с заданым шагом
+
        for (int i = 0; i <= (r.e1 - r.i1); i++)
    amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
+
        {
 +
            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++)
void massiv1 () ///создаем функцию массива
+
            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;
 +
            }
  
    mass=new double[amount]; ///создаем двумерный массив
+
         return tmp;
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
 
    {
 
         mass[l]= pow((l*step+start),3); ///при помощи массива задаем функцию с которой будем работать
 
 
     }
 
     }
    cout<< "\n";
+
};
}
 
  
void massiv2 () ///создаем функцию массива
+
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;
  
     mass=new double[amount]; ///создаем двумерный массив
+
     while(true)
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
 
 
     {
 
     {
         mass[l]= pow((l*step+start),2); ///при помощи массива задаем функцию с которой будем работать
+
    start :
    }
+
         system("cls");
    cout<< "\n";
+
        cout << "1 - Vvesti 1uu func"            << endl;
 
+
        cout << "2 - Vvesti 2uu func"            << endl;
}
+
        cout << "3 - Sloshit'"                  << endl;
 
+
        cout << "4 - Umnozhit'"                  << endl;
void interpol (double __start, double __ending, double __step) ///создаем функцию интерполяция с определением переменных
+
        cout << "5 - Vozvesti v stepen'"        << endl;
{
+
        cout << "6 - Aproximirovat'"            << endl;
 
+
        cout << "7 - Zapics' v file func"       << endl;
    double amount1=((__ending-__start)/__step)+1; ///определяем тип и подсчитываем новое количество точек с новым шагом
+
        cout << "8 - Zapics' v file aprok fun"  << endl;
    int amounti=static_cast<int>(amount1); ///преобразуем количество из типа double к типу int
+
        cout << "0 - Vihod"                      << endl;
 
+
        cin  >> vc;
    for (int i=0; i<amounti; i++) ///создаем цикл от 0 до amounti-нового количества точек
+
        switch (vc)
    {
+
        {
 
+
            case '0':
        mass1=new double[amounti];
+
                return 0 ;
        double x = i*__step+__start; ///определяем тип и расчитываем координату Х
+
            case '1':
        double x0=(static_cast<int>((x-__start)/step)) * step+__start;///определяем тип и расчитываем координату х
+
                {
                                                                      ///в интерполирующейся точке, которая стоит до новой точки
+
                system("cls");
        double x1=x0+step;///определяем тип и расчитываем координату х1 прибавляя к предыдущей точке шаг
+
                strcpy(s,"");
        int i0=(static_cast<int>((x-__start)/step));///определяем значение массива в i0 соответстующей значению функции в x0
+
                delete []a;
        int i1=i0+1;
+
                a = NULL;
        mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
+
                cout << "Vvedite imya fila" << endl;
        cout << "Х="<<i<<setw(10)<< "У= " << mass1[i] <<endl<<endl; ///выводим интерполяцию на экран
+
                cin >> s;
        ofstream fout("interpol.txt",ios::app);///сохраняем в файл
+
                strcat(s, ".txt");
        fout<< "Х="<<i<<setw(10)<< "У="<<mass1[i]<<" \n";
+
                infile.open(s);
        fout.close();
+
                infile >> n;
 
+
                a = new fun [n];
    }
+
                for(int i = 0; i < n; i ++)
 
+
                    infile >> a[i].x >> a[i].y;
    amount=amounti;
+
                f5.ad(a,n);
    delete []mass;
+
                f5.FOut();
    mass = mass1;
+
                infile.close();
 
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
}
+
                cin >> ce;
 
+
                while (true)
void aprocsimation(double __start, double __ending, double __step) ///создаем функцию апроксимация с определением переменных
+
                if (ce == 'b')
{
+
                    goto start;
 
+
                }
    int N=amount; ///определяем тип и значение переменной N (равна количеству точек с заданным шагом)
+
            case '2':
    double SumXY=0; ///определяем тип и значение переменной SumXY ( сумма (Х*У) )
+
                {
    double SumX=0; ///определяем тип и значение переменной SumX ( сумма Х )
+
                system("cls");
    double SumY=0; ///определяем тип и значение переменной SumУ ( сумма У )
+
                strcpy(s,"");
    double Sum_Xkv=0; ///определяем тип и значение переменной Sum_Xkv ( сумма (Х*Х) )
+
                delete []a;
    double Xi; ///определяем тип переменной Xi
+
                a = NULL;
 
+
                cout << "Vvedite imya fila" << endl;
    mass1 = new double[N]; ///создаем двумерный массив
+
                cin >> s;
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
+
                strcat(s, ".txt");
    {
+
                infile.open(s);
 
+
                infile >> n;
        Xi=i*__step+__start; ///расчитываем Хi
+
                a = new fun[n];
        SumXY=SumXY+Xi*mass[i]; ///расчитываем SumXY
+
                for(int i = 0; i < n; i ++)
        SumX=SumX+Xi; ///расчитываем SumX
+
                    infile >> a[i].x >> a[i].y;
        SumY=SumY+mass[i]; ///расчитываем SumY
+
                f6.ad(a,n);
        Sum_Xkv=Sum_Xkv+Xi*Xi; ///расчитываем Sum_Xkv
+
                f6.FOut();
 
+
                infile.close();
    }
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
 
+
                cin >> ce;
    double a=(SumXY*N-SumX*SumY)/(N*Sum_Xkv-SumX*SumX); ///определяем тип и расчитываем коэффициент перед Х в уравнении аХ+b
+
                while (true)
    double b=(SumY-a*SumX)/N; ///определяем тип и расчитываем свободный член в уравнении аХ+b
+
                if (ce == 'b')
 
+
                    goto start;
    if (b>0) ///если b положительное то
+
                }
    cout<<"Апроксимация: "<<a<<"*x+"<<b<<endl; ///выводим на экран: Апроксимация: а*Х+b
+
            case '3':
 
+
                system("cls");
    else if (b<0) ///если b отрицательно то
+
                f5.FOut();
    cout<<"Апроксимация: "<<a<<"*x"<<b<<endl; ///выводим на экран: Апроксимация: а*Х b
+
                f6.FOut();
 
+
                f7 = f5 + f6;
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
+
                f7.FOut();
    {
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
        mass1[i] = a*(i*__step+__start)+b; ///при помощи массива создаем функцию подсчета точек при апроксимации
+
                cin >> ce;
    }
+
                while (true)
 
+
                if (ce == 'b')
    delete[] mass;
+
                    goto start;
    mass=mass1;
+
            case '4':
    vivod();///вывод на экран
+
                system("cls");
    zapis("aprocsimation.txt");///сохраненяем в файл
+
                f5.FOut();
 
+
                f6.FOut();
}
+
                f7 = f5 * f6;
 
+
                f7.FOut();
functya operator+ ( functya F) ///перегрузка оператора +
+
                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;
  
    functya tmp(start,ending,step);
+
                cout << "done" << endl;
 
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
    mass2=new double[amount];///создаем двумерный массив
+
                cin >> ce;
    for (int i=0; i<amount; i++)
+
                while (true)
    {
+
                if (ce == 'b')
        mass2[i]=mass[i] + F.mass[i];///находим сумму двух функций
+
                    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;
 +
        }
 
     }
 
     }
    delete [] mass;
+
     return 0;
    mass=mass2;
 
    vivod();///выводим на экран результат
 
    zapis("f3.txt");///сохраненяем в файл
 
    cout<<"Введите шаг для интерполяции";
 
    cin>>step2;
 
    cout<<"Интерполяция: "<<"\n";
 
    interpol(start,ending,step2);///вызов функции интерполяции
 
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 
     return tmp;
 
 
 
 
}
 
}
 +
</syntaxhighlight>
 +
</div>
  
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];///находим разность двух функций
+
 
    }
+
Посмотреть программу можно [http://tm.spbstu.ru/Файл:main.zip здесь]
  
    delete [] mass;
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    mass=mass2;
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    vivod();///выводим на экран результат
 
    zapis("f3.txt");///сохраненяем в файл
 
    cout<<"Введите шаг для интерполяции";
 
    cin>>step2;
 
    cout<<"Интерполяция: "<<"\n";
 
    interpol(start,ending,step2);///вызов функции интерполяции
 
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 
    return tmp;
 
  
}
+
#include <iostream>
 +
#include <fstream>
 +
#include <cstring>
 +
#include <stdlib.h>
  
functya operator*( functya F)///перегрузка оператора *
+
using namespace std;
{
 
    functya tmp(start,ending,step);
 
  
    mass2=new double[amount];///создаем двумерный массив
+
ofstream outfile;
    for (int i=0; i<amount; i++)
 
    {
 
        mass2[i]=mass[i] * F.mass[i];///находим произведение двух функций
 
    }
 
  
    delete [] mass;
+
struct approx                                              //структура, необходимая для функции линейной интерполяции
    mass=mass2;
+
{
    vivod();///выводим на экран результат
+
     double koefficientA, koefficientB;
    zapis("f3.txt");///сохраненяем в файл
+
};
     cout<<"Введите шаг для интерполяции";
+
 
    cin>>step2;
+
struct dot                                                  //структура, содержащая в себе значения координат каждой точки
    cout<<"Интерполяция: "<<"\n";
+
{                                                          //по обеим осям
    interpol(start,ending,step2);///вызов функции интерполяции
+
     double x, y;
     aprocsimation(start,ending,step2);///вызов функции аппроксимации
+
};
    return tmp;
 
  
}
+
struct polyana                                              //структура, содержащая номера первого и последнего элемента каждой
 +
{                                                          //функции и количество элементов каждой из них
 +
    int a1, a2, b1, b2, k1, k2;
 +
};
  
functya operator/( functya F)///перегрузка оператора /
+
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);
 +
}
  
     functya tmp(start,ending,step);
+
class stars                                                //класс, позволяющий сохранять дискретные значения функции на
 +
{                                                          //определенном интервале с определенным шагом
 +
     private:
  
    mass2=new double[amount];///создаем двумерный массив
+
        double a;                   //первое значение функции
    for (int i=0; i<amount; i++)
+
        double b;                  //последнее значение функции
    {
+
        double step;                //шаг
         mass2[i]=mass[i] / F.mass[i];///находим частное двух функций
+
        int length;                 //длина
    }
+
         int k;                     //счетчик количества элементов
  
     delete [] mass;
+
     public:
    mass=mass2;
 
    vivod();///выводим на экран результат
 
    zapis("f3.txt");///сохраненяем в файл
 
    cout<<"Введите шаг для интерполяции ";
 
    cin>>step2;
 
    cout<<"Интерполяция: "<<"\n";
 
    interpol(start,ending,step2);///интерполяция
 
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 
    return tmp;
 
  
}
+
        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;
  
void vivod ()///создаем функцию вывода на экран
+
            length = _b - _a + 1;
{
+
            k = 0;
  
    for (int l=0; l<amount; l++)
+
            for (int i = _a ; i <= _b ; i += step)         //подсчет количества элементов функции
    {
+
            {
        cout<<"Х"<<l<<setw(10)<< "Y= " << mass[l] <<"\n";
+
                k++;
    }
+
            }
  
}
+
            massiv = new dot [k];                          //задание функции
 +
            for (int i = 0 ; i < k ; i++)
 +
              {
 +
                    massiv[i].x = _a + _step * i;
 +
                    massiv[i].y = i * 5;
 +
              }
 +
        }
  
void zapis (char Zapis[])///созданем функцию записи в файл
+
        void outinfile ()                                   //вывод в файл значений функции
{
+
        {
 +
            outfile.open ("meow", ios :: app);
  
    ofstream fout(Zapis);
+
            outfile << "x" << "          " << "y" << endl;
    for (int l=0; l<amount; l++)
+
            for (int i = 0 ; i < k ; i++)
    {
+
                {
        fout<<"X="<<l<<setw(10)<<"Y="<<mass[l]<<" \n";
+
                    outfile << massiv[i].x << "       " << massiv[i].y << endl;
    }
+
                }
 +
            outfile << endl;
 +
            outfile.close();
 +
        }
  
    fout.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;
 +
                    };
  
int main()
+
            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;
 +
                    };
  
    setlocale(LC_ALL,"RUS");
+
            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;                                     //возвращает первые и последние значения обеих функций и
 +
        }                                                  //их количества элементов
  
     double start1, ending1, step1, step2;
+
     //ПЕРЕГРУЗКА ОПЕРАТОРОВ
    int number;
 
    cout<< "Введите начало отрезка ";
 
    cin>> start1;
 
    cout<< "Введите конец отрезка ";
 
    cin>> ending1;
 
    cout<<"Введите шаг для функций ";
 
    cin>> step1;
 
  
     functya F1(start1,ending1,step1);///создаем первую функцию
+
     stars operator+ (stars & v)                             //сложение
     F1.massiv1();
+
     {
    F1.vivod();///выводим координаты первой функции на экран
+
        polyana tmp = prepare(v);
    F1.zapis("F1.txt");///записываем координаты первой функции в файл
+
        int general = tmp.k1 + tmp.k2;                      //общее количество элементов обеих функций
 
+
        stars F3(general);                                 //создание объекта класса только по количеству элементов
    cout<<"\n \n";
+
        for (int i = 0 ; i < tmp.k1 ; i++)                  //заполнение первой части окончательного результата
 
+
        {
    functya F2(start1,ending1,step1);///создаем вторую функцию
+
            F3.massiv[i].x = massiv[i+tmp.a1].x;
    F2.massiv2();
+
            trees tiger = v.love(massiv[i+tmp.a1].x);
    F2.vivod();///выводим координаты второй функции на экран
+
            if (tiger.pol == true)                          //если значения по У в одной точке не совпадают, то интерполировать
    F2.zapis("F2.txt");///записываем координаты второй функции в файл
+
            {
 +
                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;
 +
            }
  
    cout<<"\n \n";
+
        }
 +
        {
 +
          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;
 +
        }
  
    functya F3(start1, ending1, step1);
+
        for (int i = 0; i < (general); i++)                  //сортировка
 
+
        {
    cout<<"Выберите, что вы хотите сделать с функциями: 1-найти сумму, 2-найти разность, 3-найти произведение, 4-найти частное ";
+
            for (int j = 0; j < (general - 1); j ++)
    cin>>number;
+
            {
    cout<<"\n \n";
+
                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--;
 +
                }
 +
            }
 +
        }
  
    if(number==1)
 
    {
 
        F3=F1+F2;
 
    }
 
  
    else if (number==2)
+
        stars normalny (general);                          //создание элемента класса по длине
    {
+
        for (int i = 0; i < (general); i++)
         F3=F1-F2;
+
        {
 +
            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;
 
     }
 
     }
 +
    };
  
    else if (number==3)
+
        stars operator* (stars & v)                         //умножение
 
     {
 
     {
         F3=F1*(F2);
+
         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;
 +
            }
  
    else if (number==4)
+
        }
    {
+
        {
        F3=F1/F2;
+
            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;
 +
        }
  
    else
+
        for (int i= 0; i < (general); i++)
    {
+
        {
        cout<<"Ошибка ";
+
            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--;
 +
                }
 +
            }
 +
        }
  
    return 0;
+
        for (int i = 0 ; i < general ; i++)
 +
        {
  
}
+
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
</syntaxhighlight>
+
        }
</div>
 
  
'''[[Васильева Анастасия]]'''
 
  
'''Инструкция к программе''':сначала в папке с программой создаются два файла input1 и input2, в которых на первой строчке число точек в функции, а потом в два столбика значения х и у (функции должны быть с одинаковым шагом). Пользователь поочередно выбирает действия: 1 - нужно будет написать имя файла, откуда считывать значения для первой функции (х и у), 2 - для второй функции, 3 - сложение функций, пишем название файла, куда будут записываться значения, 4 - разность, 5 - умножение, 6 - интерполяция функции с шагом 0,5 , получившейся в результате сложения двух начальных,(можно сделать интерполяцию функций, которые получились в результате разности или умножения, но нужно будет в коде в case 6: newf3.Inter(0.5).output() поменять индекс функции и новый шаг), 7 - аппроксимация функции, получившейся в результате сложения двух начальных,(можно сделать аппроксимацию функций, которые получились в результате разности или умножения, но нужно будет в коде в case 7: newf3.Approxy().output() поменять индекс функции), 8 - выход.
+
        stars normalny(general);
 
+
        for (int i = 0; i < (general); i++)
'''Краткое описание алгоритма''':  функции хранятся в программе как массив точек, заданных с определённым шагом по X на заданном отрезке. Вводить значения функции в программу можно считывая координаты точек из файла. Далее с любыми функциями можно производить следующие действия: сложение, вычитание, умножение, интерполяция и аппроксимация. При этом результат каждого из этих действий - новая функция. Результаты выводятся в файл.
+
        {
Скачать программу можно по ссылке [http://tm.spbstu.ru/Файл:1.zip].
+
            normalny.massiv[i].x = F3.massiv[i].x;
 
+
            normalny.massiv[i].y = F3.massiv[i].y;
'''[[Гильманов Илья]]'''
+
        }
 
+
        a = normalny.massiv[0].x;
'''Описание программы''': программа, с помощью которой можно складывать, умножать, вычитать, делить 2-е функции, аппроксимировать,интерполировать.
+
        b = normalny.massiv[general].x;
 +
        return normalny;
 +
    }
 +
    };
  
'''Суть программы:''' Программа позволяет задать 2 функции с любыми областями определения и любыми множествами значений, интерполировать их на любом шаге, аппроксимировать, а так же сложить 2 существующие функции. Программа написана в классе работы с функциями.
+
    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;
 +
            }
  
'''Инструкция к программе''':
+
        }
1. Пользователь вводит параметры первой функции
+
        {
2. Пользователь вводит параметры второй функции
+
            for (int i = tmp.k1 ; i < (general) ; i++)
3. Происходит интерполяция первой функции по второй
+
        {
4. Пользователь выбирает арифметическую операцию
+
            F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
5. При желании пользователь может выполнить аппроксимацию полученного результата
+
            trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
 
+
            if (tiger.pol == true)
Скачать можно [[http://mech.spbstu.ru/File:Gilmanov_Func.rar здесь]]
+
            {
 
+
                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;
 +
        }
  
Скачать можно  [http://tm.spbstu.ru/File:MyFunc.zip тут].
 
  
'''[[Иванова Яна]]'''
+
        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);
 +
            }
  
'''Инструкция к программе''': Введите поочередно первый и последний элементы функций, а также их шаги. После этого введите число, соответствующее желаемому действию (соответствие указано в меню программы).
+
        }
 
+
        {
Посмотреть программу можно [http://tm.spbstu.ru/Файл:main.zip здесь]
+
            for (int i = tmp.k1 ; i < (general) ; i++)
 
+
        {
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
            F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
            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;
 +
        }
  
#include <iostream>
+
        for (int i= 0; i < (general); i++)
#include <fstream>
+
        {
#include <cstring>
+
            for (int j = 0; j < (general - 1); j ++)
#include <stdlib.h>
+
            {
 +
                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--;
 +
                }
 +
            }
 +
        }
  
using namespace std;
+
        for (int i = 0 ; i < general ; i++)
 +
        {
  
ofstream outfile;
+
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
 +
        }
  
struct approx                                              //структура, необходимая для функции линейной интерполяции
 
{
 
    double koefficientA, koefficientB;
 
};
 
  
struct dot                                                  //структура, содержащая в себе значения координат каждой точки
+
        stars normalny(general);
{                                                           //по обеим осям
+
        for (int i = 0; i < (general); i++)
    double x, y;
+
        {
};
+
            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;
 +
    }
 +
    };
  
struct polyana                                              //структура, содержащая номера первого и последнего элемента каждой
+
    trees love (double a)                                  //
{                                                           //функции и количество элементов каждой из них
+
    {
    int a1, a2, b1, b2, k1, k2;
+
        trees privet;
};
+
        for (int i = 0; i < k; i++ )
 
+
            if ((massiv[i].x < a)&& (a < massiv[i+1].x))
struct trees                                                //структура, содержащая номер элемента и логическое значение,
+
            {
{                                                          // отвечающее за нужность или не нужность интерполяции
+
                privet.n = i;
    bool pol;                                               //при равенстве или неравенстве энных элементов двух функций
+
                privet.pol = true;
    int n;
+
                return privet;
};
+
            }
                                                            //непосредственно функция линейной интерполяции
+
            else
double pentagon (double x1, double x, double x2, double y1, double y2)
+
                if (massiv[i].x == a)
{
+
                {
    return (((x - x1)/(x2- x1))*(y2 - y1) + y1);
+
                    privet.n = i;
}
+
                    privet.pol = false;
 +
                    return privet;
 +
                }
 +
                else
 +
                if (massiv[i+1].x == a)
 +
                {
 +
                    privet.n = i+1;
 +
                    privet.pol = false;
 +
                    return privet;
 +
                }
 +
    }
  
class stars                                                //класс, позволяющий сохранять дискретные значения функции на
 
{                                                          //определенном интервале с определенным шагом
 
    private:
 
  
         double a;                   //первое значение функции
+
    approx approximate ()                                  //функция аппроксимации
         double b;                   //последнее значение функции
+
    {
         double step;               //шаг
+
         approx hey;
         int length;                 //длина
+
         stars mattafix (double a, double b, double step, int k, int length);
         int k;                     //счетчик количества элементов
+
         double sigmaX = 0;
 
+
         double sigmaY = 0;
    public:
+
         double sigmaXY = 0;
 
+
         double sigmaXsqrt = 0;
         dot *massiv;
+
         for (int i = 0; i < length; i++)
         stars (int _k)                                     //конструктор для создания объекта класса - структуры
+
         {
         {                                                   //с двумя полями по количеству элементов
+
          sigmaX += a + step * i;
            massiv = new dot [_k];
+
          sigmaY += b + i * 5;
            k = _k;
+
          sigmaXY += (a + step * i)*(b + i * 5);
 +
          sigmaXsqrt += (a + step * i)*(a + step * i);
 
         }
 
         }
         stars () {};                                       //конструктор
+
         hey.koefficientA = ((k * (sigmaXY) - (sigmaX*sigmaY))/(k*sigmaXsqrt - (sigmaX * sigmaX)));
         stars (double _a, double _b, double _step)         //конструктор для создания объекта класса через начальный
+
         hey.koefficientB = ((sigmaY - hey.koefficientA*sigmaX)/k);
                                                            //и коненый элементы с определенным шагом
+
         return hey;
         {
 
            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];                           //задание функции
+
int main()
            for (int i = 0 ; i < k ; i++)
+
{
              {
+
    int tyu;
                    massiv[i].x = _a + _step * i;
+
    stars function3;
                    massiv[i].y = i * 5;
+
    int firstnumber1;
              }
+
    int firstnumber2;
        }
+
    int lastnumber1;
 +
    int lastnumber2;
 +
    int step1;
 +
    int step2;
 +
    while (true)
 +
    {
  
         void outinfile ()                                  //вывод в файл значений функции
+
         cout << "Input 0 - vvedite parametry pervoy funkcii"<< endl;
         {
+
        cout << "Input 1 - vvedite parametry vtoroy funkcii"<< endl;
            outfile.open ("meow", ios :: app);
+
         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 ;
  
            outfile << "x" << "          " << "y" << endl;
+
         switch (tyu)
            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;
+
             case 0:
            for (int i = 0 ; i < k ; i++)
+
            {  cout << "Vvedite pervy x" << endl;
                 {
+
                cin >> firstnumber1;
                    cout << massiv[i].x << "       " << massiv[i].y << endl;
+
                cout << "Vvedite posledniy x" << endl;
                 }
+
                cin >> lastnumber1;
            cout << endl;
+
                 cout << "Vvedite shag" << endl;
        }
+
                 cin >> step1;
 
+
                break;
        polyana prepare (stars &h)                          //подготовка совместной области определения для двух функций -
+
             }
        {                                                  //той части значений множества Х, на которой будут
+
             case 1:
            trees del;                                     //производиться вычисления
 
             polyana tmp;
 
             if (massiv[0].x > h.massiv[0].x)                //поиск начала совместной области определения
 
 
             {
 
             {
                 del = h.love(massiv[0].x);
+
                 cout << "Vvedite pervy x" << endl;
                 tmp.a2 = del.n + 1;
+
                 cin >> firstnumber2;
                 tmp.a1 = 0;
+
                 cout << "Vvedite posledniy x" << endl;
 +
                cin >> lastnumber2;
 +
                cout << "Vvedite shag" << endl;
 +
                cin >> step2;
 +
                break;
 
             }
 
             }
             else
+
             case 2:
                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);
+
                 stars function1 (firstnumber1, lastnumber1, step1);
                 tmp.b2 = k-1;
+
                 function1.out();
                 tmp.b1 = del.n;
+
                 function1.outinfile ();
            }
+
 
            else
+
                 stars function2 (firstnumber2, lastnumber2, step2);
                 if (massiv[k-1].x < h.massiv[k-1].x)
+
                 function2.out();
                 {
+
                function2.outinfile ();
                    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;
+
                function3 = function1 + function2;
            for (int i = tmp.a1 ; i <= tmp.b1 ; i ++)      //подсчет количества элементов первой функции
+
                function3.out();
            {
+
                function3.outinfile ();
                 tmp.k1++;
+
                 break;
 
             }
 
             }
             tmp.k2 = 0;
+
             case 3:
            for (int i = tmp.a2 ; i <= tmp.b2 ; i ++)      //подсчет количества элементов второй функции
 
 
             {
 
             {
                 tmp.k2++;
+
                 stars function1 (firstnumber1, lastnumber1, step1);
            }
+
                function1.out();
            return tmp;                                     //возвращает первые и последние значения обеих функций и
+
                function1.outinfile ();
        }                                                  //их количества элементов
 
  
    //ПЕРЕГРУЗКА ОПЕРАТОРОВ
+
                stars function2 (firstnumber2, lastnumber2, step2);
 +
                function2.out();
 +
                function2.outinfile ();
  
    stars operator+ (stars & v)                            //сложение
+
                function3 = function1 * function2;
    {
+
                function3.out();
        polyana tmp = prepare(v);
+
                function3.outinfile ();
        int general = tmp.k1 + tmp.k2;                      //общее количество элементов обеих функций
+
                break;
        stars F3(general);                                 //создание объекта класса только по количеству элементов
+
             }
        for (int i = 0 ; i < tmp.k1 ; i++)                  //заполнение первой части окончательного результата
+
             case 4:
        {
 
            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,
+
                 stars function1 (firstnumber1, lastnumber1, step1);
                                          F3.massiv[i].x,
+
                function1.out();
                                          v.massiv[tiger.n + 1].x,
+
                function1.outinfile ();
                                          v.massiv[tiger.n].y,
+
 
                                          v.massiv[tiger.n + 1].y )
+
                stars function2 (firstnumber2, lastnumber2, step2);
                                          + massiv[i+tmp.a1].y;
+
                function2.out();
 +
                function2.outinfile ();
 +
 
 +
                function3 = function1 / function2;
 +
                function3.out();
 +
                function3.outinfile ();
 +
                break;
 
             }
 
             }
             else                                            //иначе, просто сложить значения
+
             case 5:
 
             {
 
             {
                F3.massiv[i].y = v.massiv[tiger.n].y + massiv[i+tmp.a1].y;
 
            }
 
  
        }
+
                stars function1 (firstnumber1, lastnumber1, step1);
        {
+
                function1.out();
          for (int i = tmp.k1  ; i < (general) ; i++)      //заполнение второй части окончательного результата
+
                function1.outinfile ();
        {
+
 
            F3.massiv[i].x = v.massiv[i + tmp.a2 - tmp.k1].x;
+
                stars function2 (firstnumber2, lastnumber2, step2);
            trees tiger = love(v.massiv[i + tmp.a2 - tmp.k1].x);
+
                function2.out();
             if (tiger.pol == true)
+
                function2.outinfile ();
             {
+
 
                F3.massiv[i].y = pentagon  (v.massiv[tiger.n].x,
+
                function3 = function1 - function2;
                                            F3.massiv[i].x,
+
                function3.out();
                                            v.massiv[tiger.n + 1].x,
+
                function3.outinfile ();
                                            v.massiv[tiger.n].y,
+
                break;
                                            v.massiv[tiger.n + 1].y )
+
             }
                                            + v.massiv[i+tmp.a1 - tmp.k1].y;
+
             case 6:
 +
                {
 +
                    approx you;
 +
                    function3.approximate();
 +
                    outfile.open ("meow", ios :: app);
 +
                    outfile << "Y = "<< you.koefficientA <<"* x + "<<you.koefficientB << endl;
 +
                    outfile << endl;
 +
                    outfile.close();
 +
 
 +
 
 +
                }
 
             }
 
             }
            else
 
                F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
 
 
         }
 
         }
 +
    };
 +
 +
 +
</syntaxhighlight>
 +
</div>
  
        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++)
+
'''Инструкция к программе:''' Начальная координата и шаг,для задания координат функций,передаются при вызове методов,создающих функции.Начальный шаг,шаг интерполяции,а так же количество выводимых координат заданы глобально.Поэтому просто запускайте программу, при желании поменяйте заданные
        {
+
величины.
            for (int j = 0; j < (general - 1); j ++)
+
 
            {
+
Cкачать программу можно  [http://tm.spbstu.ru/Файл:Loseva.rar здесь]
                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++)
+
<div class="mw-collapsible-content">
        {
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream>
  
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
+
using namespace std;
        }
 
  
 +
#define N 5//количество точек
  
        stars normalny(general);
+
const double l1 = 5;//задаём начальный шаг функций
        for (int i = 0; i < (general); i++)
+
const double l2 = 0.7;//шаг для интерполяции
        {
 
            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)                            //вычитание
+
class Func
    {
+
{//класс,хранящий функцию,содержащий методы:печать,перегрузка,интерполяция,апроксимация
        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;
 
            }
 
  
        }
+
public:
        {
+
Func(int size) : size_(size), ax(new double[size]), by(new double[size])//создаём два массива,заполняем нулями
            for (int i = tmp.k1 ; i < (general) ; i++)
+
{
        {
+
for (int i = 0; i< size_; i++)
            F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
+
{
            trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
+
ax[i] = 0;
            if (tiger.pol == true)
+
by[i] = 0;   //все элементы обоих массивов обнуляются
            {
+
}
                F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
+
}
                                            F3.massiv[i].x,
+
 
                                            v.massiv[tiger.n + 1].x,
+
void print()//вывод на экран
                                            v.massiv[tiger.n].y,
+
{
                                            v.massiv[tiger.n + 1].y )
+
cout << "x: ";
                                            + v.massiv[i+tmp.a1 - tmp.k1].y;
+
for (int i = 0; i < size_; i++)
            }
+
cout << ax[i] << " ";
            else
+
cout << endl << "y: ";
                F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
+
for (int i = 0; i < size_; i++)
        }
+
cout << by[i] << " ";
 +
cout << endl;
 +
}
  
        for (int i= 0; i < (general); i++)
+
Func &operator+(Func &f2)//функция перегрузки:cложение функций
        {
+
{
            for (int j = 0; j < (general - 1); j ++)
+
Func *result = new Func(size_);//создаём результирующую функцию,равную сумме двух f2 и this
            {
+
for (int i = 0; i < size_; i++)
                dot temp;
+
{
                if (F3.massiv[j].x > F3.massiv[j+1].x)
+
result->ax[i] = this->ax[i];//суммируем координаты X
                {
+
result->by[i] = f2.by[i] + this->by[i];//суммируем координаты Y
                    temp = F3.massiv[j];
+
}
                    F3.massiv[j] = F3.massiv[j+1];
+
cout << "Sum f(x)=f1+f2:" << endl;//выводим на экран сумму функций
                    F3.massiv[j+1] = temp;
+
result->print();
                }
+
return *result;
                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++)
+
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;//считаем номер элемента,"левого" от искомого
  
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
+
                      //интерполируем 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]);
  
 +
}
  
        stars normalny(general);
+
result.print();//выводим результат
        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)                             //деление
+
void aprox()//Апроксимация
    {
+
{
        polyana tmp = prepare(v);
+
double a=0;
        int general = tmp.k1 + tmp.k2;
+
          for(int i=0;i<size_;i++)//считаем сумму x
        stars F3(tmp.k1 + tmp.k2);
+
  a=this->ax[i]+a;
        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);
 
            }
 
  
        }
+
double b=0;
        {
+
for(int i=0;i<size_;i++)//считаем сумму y
            for (int i = tmp.k1 ; i < (general) ; i++)
+
b=this->by[i]+b;
        {
+
            F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
+
 
            trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
+
double c=0;
            if (tiger.pol == true)
+
for(int i=0;i<size_;i++)//считаем сумму квадратов x
            {
+
c=(this->ax[i])*(this->ax[i])+c;
                F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
+
                                            F3.massiv[i].x,
+
 
                                            v.massiv[tiger.n + 1].x,
+
double d=0;
                                            v.massiv[tiger.n].y,
+
for(int i=0;i<size_;i++)//считаем сумму xy
                                            v.massiv[tiger.n + 1].y )
+
d=(this->ax[i])*(this->by[i])+d;
                                            + 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++)
+
//затем решаем систему для у=kx+m
        {
+
//(1)c*k+a*m=d
            for (int j = 0; j < (general - 1); j ++)
+
//(2)a*k+size_*m=b;
            {
+
//k=(d-am)
                dot temp;
+
//подставим в (2)
                if (F3.massiv[j].x > F3.massiv[j+1].x)
+
double m;
                {
+
m=(b*c-a*d)/(c*size_-a*a);
                    temp = F3.massiv[j];
+
double k;
                    F3.massiv[j] = F3.massiv[j+1];
+
k=(d-a*m)/c;
                    F3.massiv[j+1] = temp;
+
cout<<"aproximacia :: ";
                }
+
cout<<"y="<<k<<"x+"<<m<<endl;
                else
+
 
                if (F3.massiv[j].x == F3.massiv[j+1].x)
+
}
                {
+
 
                    int l = j;
+
 
                    while (l < general)
+
double *ax;
                    {
+
double *by;
                        F3.massiv[j].x = F3.massiv[j+1].x;
+
 
                        l++;
+
private:
                    }
+
int size_;//размер массива
                    general--;
+
};
                }
 
            }
 
        }
 
  
        for (int i = 0 ; i < general ; i++)
 
        {
 
  
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
 
        }
 
  
  
        stars normalny(general);
+
class Cord//класс,создающий и хранящий значение функций
        for (int i = 0; i < (general); i++)
+
{
        {
+
public:
            normalny.massiv[i].x = F3.massiv[i].x;
+
Cord(double x0, double s) :x0(x0), s(s)//x0-начальная координата;s-шаг
            normalny.massiv[i].y = F3.massiv[i].y;
+
{
        }
+
}
        a = normalny.massiv[0].x;
 
        b = normalny.massiv[general].x;
 
        return normalny;
 
    }
 
    };
 
  
    trees love (double a)                                   //
+
void Fyx1(Func func)//метод,считающий координаты нашей функции y=x
    {
+
{
        trees privet;
+
int i;
        for (int i = 0; i < k; i++ )
+
func.ax[0] = x0;
            if ((massiv[i].x < a)&& (a < massiv[i+1].x))
+
for (i = 1; i < N; i++)//считаются иксы
            {
+
{
                privet.n = i;
+
func.ax[i] = x0 + s;
                privet.pol = true;
+
x0 = func.ax[i];
                return privet;
+
}
            }
+
for (i = 0; i<N; i++)
            else
+
func.by[i] = func.ax[i];//считаем координаты у
                if (massiv[i].x == a)
+
cout << "f1 :" << endl;
                {
+
func.print();
                    privet.n = i;
+
cout << endl;
                    privet.pol = false;
+
}
                    return privet;
+
 
                }
+
void Fyx2(Func func)//метод,считающий координаты нашей функции y=x+1
                else
+
{
                if (massiv[i+1].x == a)
+
int i;
                {
+
func.ax[0] = x0;
                    privet.n = i+1;
+
for (i = 1; i<N; i++)//считаем иксы
                    privet.pol = false;
+
{
                    return privet;
+
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;//шаг
 +
};
  
    approx approximate ()                                   //функция аппроксимации
+
int main()
    {
+
{
        approx hey;
+
Func f1(N);//создание функции f1
        stars mattafix (double a, double b, double step, int k, int length);
+
Func f2(N);//создание f2
        double sigmaX = 0;
+
Cord s1(0, l1);//cоздаём объект s1
        double sigmaY = 0;
+
Cord s2(0, l1);//cоздаём объект s2
        double sigmaXY = 0;
+
s1.Fyx1(f1);//задаём координаты 1ой функции
        double sigmaXsqrt = 0;
+
s2.Fyx2(f2);//задаём координаты 2ой функции
        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;
 
  
 +
      //сложение функций:
 +
 +
Func f3 = f2 + f1;//есть тоже ,что и Func f3 = f2.operator+(f1);
 +
 +
f1.Int(l2);//Интерполируем f1 с новым шагом l2
 +
f1.aprox();//Апроксимируем f1
 +
 +
getchar();
 +
return 0;
 +
}
 +
 +
</syntaxhighlight>
 +
</div>
  
    }
 
};
 
  
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;
+
Скачать можно  [http://tm.spbstu.ru/File:project1.rar тут].
                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;
+
Скачать можно  [http://mech.spbstu.ru/File:%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F(%D0%A1%D1%8E%D1%80%D0%B8%D1%81%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80).zip тут].
                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();
 
  
 +
<div class="mw-collapsible-content">
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
                }
+
#include <iostream>
            }
+
#include <vector>
        }
+
#include<math.h>
    };
 
  
 +
using namespace std;
 +
class f{
 +
    private:
 +
    double st, en, d; //начало, конец, дельта
 +
    vector<double> v;//вектор, содержащий y
 +
    public:
 +
    f(double _st, double _en, double _d, vector<double> _v){
 +
        st=_st;
 +
        en=_en;
 +
        d=_d;
 +
        for(int i=0;i<_v.size();i++) //копируем массив, который вводим в консоль
 +
            v.push_back(_v[i]);
 +
        //return *this;
 +
    }
 +
    f(){};
 +
    f aprox(double _st, double _en, double _d){ //метод интерполяции, поиск коэфф a и b для y=ax+b
 +
        double sum_x=0, sum_y=0, sum_2x=0,sum_xy=0,a,b;
 +
        for(int i=0; i<=(en-st)/d; i++)
 +
            sum_x=sum_x+st+i*d;
 +
        for(int i=0; i<=(en-st)/d; i++)
 +
            sum_y=sum_y+v[i];
 +
        for(int i=0; i<=(en-st)/d; i++)
 +
            sum_2x=sum_2x+pow(st+i*d,2);
 +
        for (int i=0; i<=(en-st)/d; i++)
 +
            sum_xy=sum_xy+v[i]*(st+i*d);
 +
        a=(((en-st)/d+1)*sum_xy-sum_x*sum_y)/(((en-st)/d+1)*sum_2x-sum_x*sum_x);
 +
        b=(sum_y-a*sum_x)/(((en-st)/d+1));
  
</syntaxhighlight>
+
        vector<double> v1;//вектор, содержащий проинтерполированную функцию
</div>
+
            for(int i=0; i<=(en-st)/d; i++)
 
+
                v1.push_back(a*(st+i*d)+b);//добавление значений проинтерполированной ф-ции с шагом другой функции
'''[[Капитанюк Светлана]]'''
+
        return f(_st,_en,_d,v1);
 
 
'''Описание программы:''': программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции. функции хранятся в программе как массив точек, заданных с определенным шагом по X на заданном отрезке. Функции заданы автоматически, поэтому нет необходимости вводить каждый промежуток, нужно ввести только начало, конец и шаг. Далее пользователю на выбор будет представлено несколько операций с функциями, такие как: сложение, вычитание, умножение и деление функции одну на другую. Если функции имеют различный шаг, топеред этимони интерполируются. Так же в программе предусмотрена аппроксимация.
 
 
 
 
 
Скачать можно  [http://tm.spbstu.ru/File:Function_02.zip тут].
 
 
 
'''[[Киселёв Лев]]'''
 
'''Описание программы''':программа позволяет интерполировать и аппроксимировать значения функции, а также складывать две функции, используя перегрузку.
 
 
 
Скачать можно [[http://mech.spbstu.ru/File:Interpol.rar здесь]]
 
  
'''[[Козловская Анна]]'''
+
    }
  
'''Описание программы''': программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.
+
    f operator +(f x){//оператор сложения
 
+
        double _en,_st,_d;
'''Пояснения к алгоритму''': Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения.
+
        _en=min(en,x.en); //поиск области пересечения
 
+
        _st=max(st,x.st);
 
+
        if (_en>_st){//проверяем, пересекаются ли функции
Скачать можно  [http://tm.spbstu.ru/File:project1.rar тут].
+
            vector<double> _v;
 
+
            f y;
'''[[Лебедев Станислав]]'''
+
            if(x.st<st){ //сравниваем начала двух отрезков, для того, чтобы выбрать, какую функцию апроксимировать
 +
                vector<double> _v;
 +
                y=x.aprox(_st, _en, d);
 +
                for (int i=0; i<=(_en-_st)/d; i++)
 +
                    _v.push_back(y.v[i]+v[i]); //вектор с суммой функций
 +
                return f(_st,_en,d,_v);
 +
            }
 +
            else{
 +
                vector<double> _v;
 +
                y=this->aprox(_st, _en, x.d); //this-> функция, в которой мы работаем
 +
              for (int i=0; i<=(_en-_st)/x.d; i++)
 +
                    _v.push_back(y.v[i]+x.v[i]);
 +
                return f(_st,_en,x.d,_v);
 +
            }
 +
        }
 +
    }
  
'''Описание программы''': программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.
+
    f prot(){ //поиск противоположной функции
 +
        for (int i=0; i<=(en-st)/d; i++)
 +
            v[i]=(-1)*v[i];
 +
        return *this;
 +
    }
  
'''Пояснения к алгоритму''':
+
    f operator - (f x){ //разность функций
#  Прочитанные из файла функции нужно отсортировать.
+
        return(*this + x.prot());
#  Найти совместную область определения, то есть, найти множество пересечения областей определения функций, над которыми совершается операция.
+
    }
#  Создать третью функцию, со следующими свойствами : область определения состоит только из точек, принадлежащих совместной области определения, каждая точка области значений является результатом нужной операции над точкой области значений одной из функций и, либо интерполированной точкой по другой функции, либо, если есть возможность, точным значением из ее области значений.
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:Функции.rar тут].
+
f operator *(f x){//оператор умножения
 
+
        double _en,_st,_d;
 
+
        _en=min(en,x.en); //поиск области пересечения
<div class="mw-collapsible mw-collapsed" style="width:100%" ><div class="mw-collapsible-content">
+
        _st=max(st,x.st);
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
        if (_en>_st){//проверяем, пересекаются ли функции
#include <iostream>
+
            vector<double> _v;
#include <math.h>
+
            f y;
#include <cstring>
+
            if(x.st<st){ //сравниваем начала двух отрезков, для того, чтобы выбрать, какую функцию апроксимировать
#include <cmath>
+
                vector<double> _v;
#include <malloc.h>
+
                y=x.aprox(_st, _en, d);
#include <fstream>
+
                for (int i=0; i<=(_en-_st)/d; i++)
 +
                    _v.push_back(y.v[i]*v[i]); //вектор с суммой функций
 +
                return f(_st,_en,d,_v);
 +
            }
 +
            else{
 +
                vector<double> _v;
 +
                y=this->aprox(_st, _en, x.d); //this-> функция, в которой мы работаем
 +
              for (int i=0; i<=(_en-_st)/x.d; i++)
 +
                    _v.push_back(y.v[i]*x.v[i]);
 +
                return f(_st,_en,x.d,_v);
 +
            }
 +
        }
 +
    }
  
using namespace std;
+
f obr(){
 +
  for (int i=0; i<=(en-st)/d; i++)
 +
            v[i]=1/v[i];
 +
        return *this;
 +
}
  
double base(double x)                                       //базовая функция ( если задавать через шаг и начальный х
+
f operator /(f x){
{
+
return(*this*x.obr());
    return x;
 
 
}
 
}
  
struct ap                                                  //две одинаковые структуры это нехорошо,коненчо,но зато наглядно...
+
    void vivod(){ //вывод
{
+
     for(int i=0; i<v.size(); i++)
     double k,b;
+
        cout<<v[i]<<" ";
};
 
  
struct fun                                                  //один столбик в таблице функции
+
     }
{
 
     double x,y;
 
 
};
 
};
 +
int main(){
 +
    setlocale(LC_ALL, "Russian");
 +
    double a,b,a1,b1,d,d1,t;
 +
    int o;
 +
    cout << "Введите начала и конец отрезка и дельту: ";
 +
    cin>>a>>b>>d;
 +
    int amount=(b-a)/d+1,amount2;
 +
    vector<double>x;
 +
    cout << "Введите " << amount << " значений функции на данном интервале:";
 +
    for (int i=0; i<amount; i++)
 +
    {
 +
        cin>>t;
 +
        x.push_back(t);
 +
    }
  
struct sf                                                  //структура нужная, для возражеия значений из функции "prepare" класса F
+
    cout << "Проделаем ровно то же самое для 2 функции ";
{
+
     cout << "Введите начала и конец отрезка и дельту: ";
     int i1,i2,e1,e2;
+
     cin >> a1 >> b1 >> d1;
     double glength, gfirstx, glastx;
 
};
 
  
double intr(double x1,double x2,double x,double y1,double y2)  // линенейная интерполяция
+
     amount2=(b1-a1)/d1+1;
{
+
     vector<double>y;
     return ( ((x-x1)/(x2-x1)) * (y2-y1) + y1 );
+
     cout << "Введите " << amount2 << " значений функции на данном интервале:";
}
+
     for (int i=0; i<amount2; i++)
 
 
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;
+
         cin>>t;
         x  += b[i].x;
+
         y.push_back(t);
        y  += b[i].y;
 
        sqx += b[i].x*b[i].x;
 
        xsq += b[i].x;
 
 
     }
 
     }
     xsq *= xsq;
+
     f g(a,b,d,x);
 +
    f h(a1,b1,d1,y);
  
     r.k = (n*xy - x*y)/(n*sqx - xsq);                       //использование формул
+
     cout<<"Выберете дейстивя с функциями: +, -, *, \ " << endl;
     r.b = (y - r.k*x)/n;
+
    cout<<"Введите число, соответсвующее порядковому номеру операции(1-4) - ";
    return r;
+
    cin>>o;
}
+
    if(o==1){              //по невыясненным причинам одновременно написанные слева идущие if -ы не работают,
 +
        cout<<"Сумма:";     //но если заккоментить их и менять знак + в скобке на другие, то все работает
 +
        (g+h).vivod();
  
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;
 
  
 
+
    if(o==2){
        for (int i = 0;i < length; i ++)
+
         cout<<"Разность:"
         {
+
        (g-h).vivod();
            a[i].y = base(firstx + i*step);
 
            a[i].x = firstx + i*step;
 
        }
 
  
 
     }
 
     }
  
     F (fun b[],int l)                                   //конструктор для создания фунции с уже известными областями определния и значений
+
     if(o==3){
    {
+
         cout<<"Произведение:"
         length = l;
+
         (g*h).vivod();
         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[] )                           //позволяет создать и заполнить переданным массивом поле объекта класса
+
    if(o==3){
    {
+
         cout<<"Отношение:"
         a = new fun [l];
+
         (g/h).vivod();
         for (int i = 0; i < l; 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;
 
    }
 
  
 +
}
 +
 +
</syntaxhighlight>
 +
</div>
  
    double getely(int i)                              //возращает значение из поля "х" iого элемента
 
    {
 
        return a[i].y;
 
    }
 
  
     int getlength()                                 //возращает размер области определения функции(в точках)
+
 
 +
 
 +
 
 +
 
 +
'''[[Андреева Полина]]'''
 +
 
 +
'''Инструкция к программе:''' пользователь должен ввести начало, конец и шаг. Создается две функции. Затем на экране появляется один из знаков арифметических действий. Пользователь выбирает один из знаков. Создается третья функция. Пользователь вводит второй шаг. Функция интерполируется по этому новому шагу, а затем аппроксимируется.
 +
'''Краткое описание алгоритма :''' в классе создается две функции(с помощью массивов). Так же в классе есть такие методы: перегрузка арифм операций, интерполяция, аппроксимация, вывод массивов на экран и их сохранение в файл. Сначала создается два массива для функций. Затем  с помощью перегрузки эти два массива складываются/умножаются/делятся/вычитаются и записываются опять в этот массив. В методе перегрузки сразу вызывается интерполяция и аппроксимация.
 +
[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)
 
     {
 
     {
         return length;
+
         AmountDouble=((End-Begin)/Step)+1;///количество точек с данным шагом
    }
+
        AmountInt=static_cast<int>(AmountDouble);///так как количество это целое число, то округляем
  
    void FOut()                                    //выводит функцию на экран
 
    {
 
      cout << "  x        y" << endl;
 
      for (int i = 0;i < length; i ++)
 
          cout << "  " << a[i].x << "        " << a[i].y << endl;
 
      cout << endl;
 
 
     }
 
     }
  
 
+
     void massiv1() ///создание первой функции х^3
     int pfind(double x)const                        //возращает либо номер элемента,идущщий перед элементом, большим,чем х; в случае нахождения равного, возращает число, противоположное номеру следующего элемента(иначе может вернуться нуль,а нуль знака не имееет)
 
 
     {
 
     {
         for (int i = 0; i < length-1; i++ )
+
        mass=new double[AmountInt];
 +
         for (int l=0; l<AmountInt; l++)
 
         {
 
         {
             if (((a[i].x < x) && (a[i + 1].x > x)))
+
             mass[l] =pow((l*Step+Begin),3);
                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;
+
        cout << "y=x^3 \n";
        return -1;
 
 
     }
 
     }
 
+
     void massiv2() ///создание второй функции sin(x)
     sf prepare(F &x)const                                      //"подготовка" функций к бинарной операции (нахождение совместной области определения
 
 
     {
 
     {
         sf r;
+
         mass=new double[AmountInt];
         if (a[0].x > x.a[0].x)
+
         for (int l=0; l<AmountInt; l++)
 
         {
 
         {
             r.gfirstx = a[0].x;
+
             mass[l] =sin(l*Step+Begin);
            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
+
         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-это точки функции с новыми шагами
 
         {
 
         {
             r.gfirstx = x.a[0].x;
+
             mass1 = new double[NewAmountInt];
             double k = pfind(x.a[0].x);
+
            double x = i*__Step+__Begin;///значения х в новых точках
             if (k < 0)
+
             double x0=(static_cast<int>((x-__Begin)/Step)) * Step+__Begin;///значение х в точке интерполяции
                r.i1 = -k - 1;
+
            ///стоящей ДО новой точки
             else
+
            double x1=x0+Step;///точка интерполяции ПОСЛЕ новой точки, т.е к предыдущей прибавляем СТАРЫЙ шаг
                r.i1 = (k - 1) + 1;
+
             int i0=(static_cast<int>((x-__Begin)/Step));///это нужно для массива, значение массива в i0 соответстует значению функции в x0
             r.i2 = 0;
+
            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)
  
         if (a[length - 1].x < x.a[x.length - 1].x)
+
    {
 +
         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++)
 
         {
 
         {
             r.glastx = a[length - 1].x;
+
             x=i*__Step+__Begin;///такие значения принимает x в точках по порядку i
             r.e1 = length - 1;
+
             SumXMass=SumXMass+x*mass[i];
             double k = x.pfind(r.glastx);
+
             SumX=SumX+x;
             if (k < 0)
+
             SumMass=SumMass+mass[i];
                r.e2 = -k - 1;
+
             SumXX=SumXX+x*x;
             else
+
 
                r.e2 = (k - 1) - 1;
 
 
         }
 
         }
         else
+
        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++)
 
         {
 
         {
             r.glastx = x.a[x.length - 1].x;
+
             mass1[i] = a*(i*__Step+__Begin)+b;///такие значения принимает апроксимация
            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));
+
         delete[] mass;
 +
        mass=mass1;
 +
        output();///вывод на экран
 +
        SaveFile("approximation.txt");///сохранение в файл
 +
        cout<<"end of appox";
  
        return r;
 
 
     }
 
     }
  
     void ad (fun b[],int l)                                 //присвоить массиву объекта класса F значения массива b
+
     func operator+( func f)///перегрузка оператора +
 
     {
 
     {
         length = l;
+
         func newmass(Begin, End, Step);
         a = new fun [l];
+
         masss=new double[AmountInt];///новая функция равная сумме данныйх функций
         for (int i = 0; i < l;i++)
+
         for (int i=0; i<AmountInt; i++)
             a[i] = b[i];
+
        {
         firstx = a[0].x;
+
             masss[i] = mass[i] + f.mass[i];
         lastx = a[length - 1].x;
+
         }
    }
+
        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;
  
    fun *geta()                                        //получения указателя на начало массива в поле класса
 
    {
 
        return a;
 
 
     }
 
     }
  
     F operator +(F &x) const                              //сложение двух функций
+
     func operator-( func f)
 
     {
 
     {
         int i1, e1, i2, e2, kk = 0;
+
         func newmass(Begin, End, Step);
         double gfirstx, glastx, glength;
+
         masss=new double[AmountInt];
 
+
         for (int i=0; i<AmountInt; i++)
         if (((x.lastx < firstx) && (x.firstx < firstx)) || ((lastx < x.firstx) && (firstx < x.firstx)))
 
 
         {
 
         {
             cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
+
             masss[i] = mass[i] - f.mass[i];
            F fl(-1,0,0);
 
            return fl;
 
 
         }
 
         }
         sf r = prepare(x);
+
         delete [] mass;
         F tmp(r.glength,r.gfirstx,r.glastx);
+
        mass = masss;
         for (int i = 0; i <= (r.e1 - r.i1); i++)
+
        output();
         {
+
         SaveFile("f3.txt");
            tmp.a[i].x = a[i + r.i1].x;            //поправка,введенная таким образом,чтобы номер,с которого начинается отсчет был первым в новой области определения
+
         cout<<"enter new step";
            int ii = x.pfind(tmp.a[i].x);
+
        cin>>Step2;
            if (ii < 0)
+
        cout<<"interpolation: ";
                tmp.a[i].y = x.a[-ii - 1].y + a[i + r.i1].y;
+
        interpolation(Begin,End,Step2);
            else
+
         cout<<" approximation: ";
                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;
+
        approximation(Begin,End,Step2);
        }
+
        return newmass;
         for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
+
    }
 +
    func operator/( func f)
 +
    {
 +
        func newmass(Begin, End, Step);
 +
        masss=new double[AmountInt];
 +
         for (int i=0; i<AmountInt; i++)
 
         {
 
         {
             int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
+
             masss[i] = mass[i] / f.mass[i];
            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 --;
 
            }
 
 
         }
 
         }
 
+
        cout << " division: \n ";
         for (int i = 0; i < glength; i++)
+
         delete [] mass;
            for (int j = 0; j < glength - 1; j++)
+
        mass = masss;
            if (tmp.a[j].x > tmp.a[j + 1].x)
+
        output();
            {
+
        SaveFile("f3.txt");
                fun t = tmp.a[j];
+
        cout<<"enter new step";
                tmp.a[j] = tmp.a[j + 1];
+
        cin>>Step2;
                tmp.a[j + 1] = t;
+
        cout<<"interpolation: ";
            }
+
        interpolation(Begin,End,Step2);
 
+
        cout<<" approximation: ";
         return tmp;
+
        approximation(Begin,End,Step2);
}
+
         return newmass;
 
+
    }
     F operator *(F & x) const                                        //умножение двух функций
+
     func operator*( func f)
 
     {
 
     {
         int i1, e1, i2, e2, kk = 0;
+
         func newmass(Begin, End, Step);
         double gfirstx, glastx, glength;
+
         masss=new double[AmountInt];
 
+
         for (int i=0; i<AmountInt; i++)
         if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
 
 
         {
 
         {
             cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
+
             masss[i] = mass[i] * f.mass[i];
            F fl(-1,0,0);
 
            return fl;
 
 
         }
 
         }
 +
        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;
 +
    }
  
        sf r = prepare(x);
+
 
        F tmp(r.glength,r.gfirstx,r.glastx);
+
    void output()///вывод функции на экран
 
+
    {
         for (int i = 0; i <= (r.e1 - r.i1); i++)
+
         for (int i=0; i<AmountInt; i++)
 
         {
 
         {
             tmp.a[i].x = a[i + r.i1].x;
+
             cout << "y("<<i<< ") = " << mass[i] <<endl;
            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++)
+
    }
 +
 
 +
 
 +
    void SaveFile(char filename[])///сохранение функции в файл
 +
    {
 +
        std::ofstream fout(filename);
 +
         for (int l=0; l<AmountInt; l++)
 
         {
 
         {
             int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
+
             fout<<l<<" "<<mass[l]<<" \n";
            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++)
+
         fout.close();
            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)))
+
int main()
        {
+
{
            cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
 
            F fl(-1,0,0);
 
            return fl;
 
        }
 
  
        sf r = prepare(x);
+
    double Begin1, End1, Step1, Step2;
        F tmp(r.glength,r.gfirstx,r.glastx);
+
    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;
  
        for (int i = 0; i <= (r.e1 - r.i1); i++)
+
    func f1(Begin1,End1,Step1);///создание первой функции
        {
+
    f1.massiv1();
            tmp.a[i].x = a[i + r.i1].x;
+
    f1.output();
            int ii = x.pfind(tmp.a[i].x);
+
    cout<<"\n ";
            if (ii < 0)
+
    f1.SaveFile("f1.txt");
                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++)
+
    func f2(Begin1,End1,Step1);///создание второй функции
            for (int j = 0; j < glength - 1; j++)
+
    f2.massiv2();
            if (tmp.a[j].x > tmp.a[j + 1].x)
+
    f2.output();
            {
+
    cout<<"\n ";
                fun t = tmp.a[j];
+
    f2.SaveFile("f2.txt");
                tmp.a[j] = tmp.a[j + 1];
+
    cout<<"\n";
                tmp.a[j + 1] = t;
 
            }
 
  
        return tmp;
+
     func f3(Begin1,End1,Step1);
     }
 
};
 
  
int main()
+
     cout<<" \n \n choose 1 - sum , 2 - subtract, 3 - division, 4 - multiply \n";///выбор операции
{
+
     int z;
  /*
+
     cin>>z;
     F f1(5,-2,1.5);
+
     switch (z)
    F f2(30,-10,0.5);
+
     {
     F f3, f4;
+
     case 1:
     f1.FOut();
+
     {
     f2.FOut();
+
        f3=f1+f2;///сумма функций
     f3 = f1 + f2;
+
        break;
     f3.FOut();
+
     }
     f4 = f1 * f2;
+
     case 2:
    f4.FOut();
 
    cout << " ________" << endl;
 
*/
 
    char vc, s[255], ce;
 
     ifstream infile;
 
     int n;
 
    fun *a;
 
    F f5,f6,f7,f8,f9;
 
 
 
    while(true)
 
 
     {
 
     {
    start :
+
         f3=f1-f2;
         system("cls");
+
         break;
         cout << "1 - Vvesti 1uu func"            << endl;
+
    }
         cout << "2 - Vvesti 2uu func"            << endl;
+
    case 3:
         cout << "3 - Sloshit'"                  << endl;
+
    {
        cout << "4 - Umnozhit'"                  << endl;
+
         f3=f1/f2;
         cout << "5 - Vozvesti v stepen'"        << endl;
+
         break;
         cout << "6 - Aproximirovat'"            << endl;
+
    }
        cout << "7 - Zapics' v file func"        << endl;
+
    case 4:
        cout << "8 - Zapics' v file aprok fun"  << endl;
+
    {
         cout << "0 - Vihod"                     << endl;
+
         f3=f1*f2;
         cin  >> vc;
+
         break;
        switch (vc)
+
    }
        {
+
 
            case '0':
+
    default :
                return 0 ;
+
    {
            case '1':
+
         cout<<"NOOOOO";
                {
+
         break;
                system("cls");
+
    }
                strcpy(s,"");
+
    };
                delete []a;
+
    return 0;
                a = NULL;
+
}
                cout << "Vvedite imya fila" << endl;
+
 
                cin >> s;
+
 
                strcat(s, ".txt");
+
</syntaxhighlight>
                infile.open(s);
+
</div>
                infile >> n;
+
 
                a = new fun [n];
+
 
                for(int i = 0; i < n; i ++)
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
                    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)
+
Скачать программу можно по ссылке  [http://tm.spbstu.ru/Файл:задача_2.zip].
                if (ce == 'b')
+
 
                    goto start;
+
<div class="mw-collapsible-content">
                }
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
            case '2':
+
#include <iostream>
                {
+
#include <locale.h>
                system("cls");
+
#include <math.h>
                strcpy(s,"");
+
#include <fstream>
                delete []a;
+
#include<iomanip>
                a = NULL;
+
 
                cout << "Vvedite imya fila" << endl;
+
using namespace std;
                cin >> s;
+
 
                strcat(s, ".txt");
+
class functya ///создаем класс функции
                infile.open(s);
+
{
                infile >> n;
+
 
                a = new fun[n];
+
private: ///объявляем тип переменных в привате
                for(int i = 0; i < n; i ++)
+
    double *mass, *mass1, *mass2; ///*mass, *mass1, *mass2 -определение двумерного массива
                    infile >> a[i].x >> a[i].y;
+
    double start, ending, step, step2, amountdouble; ///start-начало, ending-конец, step-шаг, amountdouble-количество точек (типа double)
                f6.ad(a,n);
+
 
                f6.FOut();
+
public: ///объявляем тип переменных в паблике
                infile.close();
+
    int amount; ///amoun-количество точек (типа int)
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
 
                cin >> ce;
+
functya (double _start, double _ending, double _step):start(_start),ending(_ending),step(_step) ///создаем конструктор функции с объявлением переменных
                while (true)
+
{
                if (ce == 'b')
+
 
                    goto start;
+
    amountdouble=((ending-start)/step)+1; ///подсчитываем количество точек с заданым шагом
                }
+
    amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
            case '3':
+
 
                system("cls");
+
}
                f5.FOut();
+
 
                f6.FOut();
+
void massiv1 () ///создаем функцию массива
                f7 = f5 + f6;
+
{
                f7.FOut();
+
 
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
    mass=new double[amount]; ///создаем двумерный массив
                cin >> ce;
+
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
                while (true)
+
    {
                if (ce == 'b')
+
        mass[l]= pow((l*step+start),3); ///при помощи массива задаем функцию с которой будем работать
                    goto start;
+
    }
            case '4':
+
    cout<< "\n";
                system("cls");
+
}
                f5.FOut();
+
 
                f6.FOut();
+
void massiv2 () ///создаем функцию массива
                f7 = f5 * f6;
+
{
                f7.FOut();
+
 
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
    mass=new double[amount]; ///создаем двумерный массив
                cin >> ce;
+
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
                while (true)
+
    {
                if (ce == 'b')
+
        mass[l]= pow((l*step+start),2); ///при помощи массива задаем функцию с которой будем работать
                    goto start;
+
    }
            case '5':
+
    cout<< "\n";
                system("cls");
+
 
                f5.FOut();
+
}
                f6.FOut();
+
 
                f7 = f5 ^ f6;
+
void interpol (double __start, double __ending, double __step) ///создаем функцию интерполяция с определением переменных
                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;
+
    double amount1=((__ending-__start)/__step)+1; ///определяем тип и подсчитываем новое количество точек с новым шагом
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
    int amounti=static_cast<int>(amount1); ///преобразуем количество из типа double к типу int
                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>
 
  
'''[[Лобанов Илья]]'''
+
    for (int i=0; i<amounti; i++) ///создаем цикл от 0 до amounti-нового количества точек
 +
    {
  
'''Описание программы''':
+
        mass1=new double[amounti];
Программа позволяет складывать , вычитать , делить,умножать 2 функции,заданные на одном интервале.При считывании с файла сначала указывается отрезок, потом величина шага, а потом дискретные значения.
+
        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();
  
Скачать можно [[http://tm.spbstu.ru/File:func.rar тут]]
+
    }
  
 +
    amount=amounti;
 +
    delete []mass;
 +
    mass = mass1;
  
'''[[Лосева Татьяна]]'''
+
}
 
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.
 
 
 
'''Инструкция к программе:''' Начальная координата и шаг,для задания координат функций,передаются при вызове методов,создающих функции.Начальный шаг,шаг интерполяции,а так же количество выводимых координат заданы глобально.Поэтому просто запускайте программу, при желании поменяйте заданные
 
величины.
 
  
Cкачать программу можно  [http://tm.spbstu.ru/Файл:Loseva.rar здесь]
+
void aprocsimation(double __start, double __ending, double __step) ///создаем функцию апроксимация с определением переменных
 +
{
  
<div class="mw-collapsible-content">
+
    int N=amount; ///определяем тип и значение переменной N (равна количеству точек с заданным шагом)
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    double SumXY=0; ///определяем тип и значение переменной SumXY ( сумма (Х*У) )
#include <iostream>
+
    double SumX=0; ///определяем тип и значение переменной SumX ( сумма Х )
 +
    double SumY=0; ///определяем тип и значение переменной SumУ ( сумма У )
 +
    double Sum_Xkv=0; ///определяем тип и значение переменной Sum_Xkv ( сумма (Х*Х) )
 +
    double Xi; ///определяем тип переменной Xi
  
using namespace std;
+
    mass1 = new double[N]; ///создаем двумерный массив
 +
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
 +
    {
  
#define N 5//количество точек
+
        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
  
const double l1 = 5;//задаём начальный шаг функций
+
    }
const double l2 = 0.7;//шаг для интерполяции
 
  
class Func
+
    double a=(SumXY*N-SumX*SumY)/(N*Sum_Xkv-SumX*SumX); ///определяем тип и расчитываем коэффициент перед Х в уравнении аХ+b
{//класс,хранящий функцию,содержащий методы:печать,перегрузка,интерполяция,апроксимация
+
    double b=(SumY-a*SumX)/N; ///определяем тип и расчитываем свободный член в уравнении аХ+b
  
public:
+
    if (b>0) ///если b положительное то
Func(int size) : size_(size), ax(new double[size]), by(new double[size])//создаём два массива,заполняем нулями
+
    cout<<"Апроксимация: "<<a<<"*x+"<<b<<endl; ///выводим на экран: Апроксимация: а*Х+b
{
 
for (int i = 0; i< size_; i++)
 
{
 
ax[i] = 0;
 
by[i] = 0;  //все элементы обоих массивов обнуляются
 
}
 
}
 
  
void print()//вывод на экран
+
    else if (b<0) ///если b отрицательно то
{
+
    cout<<"Апроксимация: "<<a<<"*x"<<b<<endl; ///выводим на экран: Апроксимация: а*Х b
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ложение функций
+
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
{
+
    {
Func *result = new Func(size_);//создаём результирующую функцию,равную сумме двух f2 и this
+
        mass1[i] = a*(i*__step+__start)+b; ///при помощи массива создаем функцию подсчета точек при апроксимации
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) //метод Интерполяции
+
    delete[] mass;
{
+
    mass=mass1;
int M = (this->ax[this->size_ - 1] - this->ax[0]) / L + 1; //M- количество элементов массива с координатами интерполирующей функции;
+
    vivod();///вывод на экран
Func result = Func(M);//cоздаём функцию,в кторой будет храниться результат интерполяции
+
    zapis("aprocsimation.txt");///сохраненяем в файл
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]);
 
  
}
+
functya operator+ ( functya F) ///перегрузка оператора +
 +
{
  
result.print();//выводим результат
+
    functya tmp(start,ending,step);
}
 
  
void aprox()//Апроксимация
+
    mass2=new double[amount];///создаем двумерный массив
{
+
    for (int i=0; i<amount; i++)
double a=0;
+
    {
          for(int i=0;i<size_;i++)//считаем сумму x
+
        mass2[i]=mass[i] + F.mass[i];///находим сумму двух функций
  a=this->ax[i]+a;
+
    }
       
+
    delete [] mass;
 +
    mass=mass2;
 +
    vivod();///выводим на экран результат
 +
    zapis("f3.txt");///сохраненяем в файл
 +
    cout<<"Введите шаг для интерполяции";
 +
    cin>>step2;
 +
    cout<<"Интерполяция: "<<"\n";
 +
    interpol(start,ending,step2);///вызов функции интерполяции
 +
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 +
    return tmp;
  
double b=0;
+
}
for(int i=0;i<size_;i++)//считаем сумму y
 
b=this->by[i]+b;
 
 
  
double c=0;
+
functya operator-( functya F)///перегрузка оператора -
for(int i=0;i<size_;i++)//считаем сумму квадратов x
+
{
c=(this->ax[i])*(this->ax[i])+c;
 
 
  
double d=0;
+
    functya tmp(start,ending,step);
for(int i=0;i<size_;i++)//считаем сумму xy
 
d=(this->ax[i])*(this->by[i])+d;
 
 
  
//затем решаем систему для у=kx+m
+
    mass2=new double[amount];///создаем двумерный массив
//(1)c*k+a*m=d
+
    for (int i=0; i<amount; i++)
//(2)a*k+size_*m=b;
+
    {
//k=(d-am)
+
        mass2[i]=mass[i] - F.mass[i];///находим разность двух функций
//подставим в (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;
 
  
}
+
    delete [] mass;
 
+
    mass=mass2;
 
+
    vivod();///выводим на экран результат
double *ax;
+
    zapis("f3.txt");///сохраненяем в файл
double *by;
+
    cout<<"Введите шаг для интерполяции";
 +
    cin>>step2;
 +
    cout<<"Интерполяция: "<<"\n";
 +
    interpol(start,ending,step2);///вызов функции интерполяции
 +
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 +
    return tmp;
  
private:
+
}
int size_;//размер массива
 
};
 
  
 +
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;
  
class Cord//класс,создающий и хранящий значение функций
+
}
 +
 
 +
functya operator/( functya F)///перегрузка оператора /
 
{
 
{
public:
 
Cord(double x0, double s) :x0(x0), s(s)//x0-начальная координата;s-шаг
 
{
 
}
 
  
void Fyx1(Func func)//метод,считающий координаты нашей функции y=x
+
    functya tmp(start,ending,step);
{
+
 
int i;
+
    mass2=new double[amount];///создаем двумерный массив
func.ax[0] = x0;
+
    for (int i=0; i<amount; i++)
for (i = 1; i < N; i++)//считаются иксы
+
    {
{
+
        mass2[i]=mass[i] / F.mass[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
+
    delete [] mass;
{
+
    mass=mass2;
int i;
+
    vivod();///выводим на экран результат
func.ax[0] = x0;
+
    zapis("f3.txt");///сохраненяем в файл
for (i = 1; i<N; i++)//считаем иксы
+
    cout<<"Введите шаг для интерполяции ";
{
+
    cin>>step2;
func.ax[i] = x0 + s;
+
    cout<<"Интерполяция: "<<"\n";
x0 = func.ax[i];
+
    interpol(start,ending,step2);///интерполяция
}
+
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
for (i = 0; i<N; i++)
+
    return tmp;
func.by[i] = func.ax[i] + 1;//считаем игрики
 
cout << "f2 :" << endl;
 
func.print();
 
cout << endl;
 
}
 
  
private:
+
}
double x0;//начальная координата
 
double s;//шаг
 
};
 
  
int main()
+
void vivod ()///создаем функцию вывода на экран
 
{
 
{
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ой функции
 
  
      //сложение функций:
+
    for (int l=0; l<amount; l++)
+
    {
Func f3 = f2 + f1;//есть тоже ,что и Func f3 = f2.operator+(f1);
+
        cout<<"Х"<<l<<setw(10)<< "Y= " << mass[l] <<"\n";
 +
    }
  
f1.Int(l2);//Интерполируем f1 с новым шагом l2
 
f1.aprox();//Апроксимируем f1
 
 
getchar();
 
return 0;
 
 
}
 
}
  
</syntaxhighlight>
+
void zapis (char Zapis[])///созданем функцию записи в файл
</div>
+
{
 +
 
 +
    ofstream fout(Zapis);
 +
    for (int l=0; l<amount; l++)
 +
    {
 +
        fout<<"X="<<l<<setw(10)<<"Y="<<mass[l]<<" \n";
 +
    }
 +
 
 +
    fout.close();
  
'''[[Сергей Ляжков]]'''
+
}
'''Описание программы''':программа позволяет проводить следующие действия с функциями: сложение, вычитание, умножение, те же действия с числами, проводить аппроксимацию и интерполяцию
 
Скачать можно [[http://tm.spbstu.ru/File:Функции.zip тут]]
 
  
<br>'''[[Нарядчиков Александр]]'''<br>
+
};
'''Инструкция:''' Пользователю достаточно просто запустить программу.<br>
 
'''Описание программы:''' В окне рисуются графики с разным шагом, количеством точек, начальными и конечными координатами, по клавише 'G' происходит их кубическая интерполяция, также рисуется график их суммы. По клавише 'S' можно сохранить полученный график в текстовый документ в виде координат его точек. По клавише 'L' можно загрузить график из текстового документа, и он появится в окне программы. Также происходит линейная аппроксимация графика суммы, и график аппроксимации рисуется на экран.<br>
 
'''Описание алгоритма:''' Вся графика написана с помощью библиотек OpenGL и GLUT. Кубическая интерполяция написана с помощью кривых Безье(интерполяция по четырем точкам - кубическая кривая). При сложение двух графиков происходит их интерполяция, для приведения их к общему шагу. Линейная аппроксимация написана с помощью метода наименьших квадратов.<br>
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
"'''T05GRAPH.CPP'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
/* FILENAME: T05GRAPH.CPP
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#include "GRAPH.H"
+
int main()
 +
{
  
/* Глобальные переменные */
+
    setlocale(LC_ALL,"RUS");
// Глобальная переменная, хранящая время в секундах с момента старта программы
 
double SyncTime;
 
// Глобальные переменные для отслеживания нажатия клавиш
 
bool IsGraph, IsSave, IsLoad, IsLoaded;
 
  
/* Timer function */
+
    double start1, ending1, step1, step2;
// Подсчет времени
+
    int number;
void Timer( void )
+
    cout<< "Введите начало отрезка ";
{
+
    cin>> start1;
long t;
+
    cout<< "Введите конец отрезка ";
static long StartTime = -1;
+
    cin>> ending1;
 +
    cout<<"Введите шаг для функций ";
 +
    cin>> step1;
  
t = clock();
+
    functya F1(start1,ending1,step1);///создаем первую функцию
if (StartTime == -1)
+
    F1.massiv1();
StartTime = t;
+
    F1.vivod();///выводим координаты первой функции на экран
SyncTime = (double)(t - StartTime) / CLOCKS_PER_SEC;
+
    F1.zapis("F1.txt");///записываем координаты первой функции в файл
} /* End of 'Timer' function */
 
  
/* Display function */
+
    cout<<"\n \n";
// Стандартная функция, вызываемая при перерисовке окна
 
void Display( void )
 
{
 
graph G1(-15, 15, 0.1), G2(2, 10, 0.4), G3, G4;
 
  
// Запуск времени
+
    functya F2(start1,ending1,step1);///создаем вторую функцию
Timer();
+
    F2.massiv2();
 +
    F2.vivod();///выводим координаты второй функции на экран
 +
    F2.zapis("F2.txt");///записываем координаты второй функции в файл
  
// Установка цвета закраски фона в белый
+
    cout<<"\n \n";
glClearColor(1, 1, 1, 1);
 
// Очищаем цветовой буфер для создания нового изображения
 
glClear(GL_COLOR_BUFFER_BIT);
 
  
glLoadIdentity();
+
    functya F3(start1, ending1, step1);
glScaled(0.1 / (1366 / 768.0), 0.1, 0.1);
 
  
// Отрисовка осей X и Y
+
    cout<<"Выберите, что вы хотите сделать с функциями: 1-найти сумму, 2-найти разность, 3-найти произведение, 4-найти частное ";
glBegin(GL_LINE_STRIP);
+
    cin>>number;
 +
    cout<<"\n \n";
  
glColor3d(0, 0, 1);
+
    if(number==1)
glVertex2d(0, -1000);
+
    {
glVertex2d(0, 1000);
+
        F3=F1+F2;
 +
    }
  
glColor3d(1, 0, 0);
+
    else if (number==2)
glVertex2d(-1000, 0);
+
    {
glVertex2d(1000, 0);
+
        F3=F1-F2;
 +
    }
  
glEnd();
+
    else if (number==3)
 +
    {
 +
        F3=F1*(F2);
 +
    }
 +
 
 +
    else if (number==4)
 +
    {
 +
        F3=F1/F2;
 +
    }
 +
 
 +
    else
 +
    {
 +
        cout<<"Ошибка ";
 +
    }
 +
 
 +
    return 0;
 +
 
 +
}
 +
</syntaxhighlight>
 +
</div>
  
/* Отрисовка графиков */
 
// Отрисовка первого графика и его интерполяция по клавише "G"
 
G1.Draw(sin);
 
if (IsGraph == 1)
 
G1.Interpolation_Draw(1.0 / 32);
 
  
// Отрисовка второго графика и его интерполяция по клавише "G"
 
G2.Draw(log);
 
if (IsGraph == 1)
 
G2.Interpolation_Draw(1.0 / 32);
 
  
// Отрисовка графика суммы для первого и второго графиков
+
'''[[Уманский Александр]]'''
G3 = G2 + G1;
 
glColor3d(0, 1, 0);
 
G3.Draw();
 
// Аппроксимация графика суммы
 
G3.Approximation();
 
  
// Сохранение графика по клавише "S"
+
'''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется.
if (IsSave == 1)
 
{
 
G3.SaveArray();
 
IsSave == 0;
 
}
 
 
// Загрузка графика по клавише "L"
 
if (IsLoad == 1)
 
{
 
delete[] G4.mas;
 
delete[] G4.Color;
 
G4.LoadArray("graph.txt");
 
IsLoad == 0;
 
IsLoaded = 1;
 
}
 
 
// Отрисовка загруженного графика
 
if (IsLoaded == 1)
 
{
 
glColor3d(1, 0, 0);
 
G4.Draw();
 
IsLoaded = 0;
 
}
 
  
// Чистка памяти
 
delete[] G1.mas;
 
delete[] G1.Color;
 
delete[] G2.mas;
 
delete[] G2.Color;
 
delete[] G3.mas;
 
delete[] G3.Color;
 
delete[] G4.mas;
 
delete[] G4.Color;
 
  
glFinish();
 
// Копируем вторичный буфер в окно
 
glutSwapBuffers();
 
// Вызываем функцию обновления кадра
 
glutPostRedisplay();
 
} /* End of 'Display' function */
 
  
/* Keyboard function */
+
Скачать программу можно по [http://mech.spbstu.ru/File:Untitled1.rar ссылке]
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
void Keyboard( unsigned char Key, int X, int Y )
+
Метод наименьших квадратов
{
+
задача состоит в том, чтобы минимизировать выражение:
// Выход из программы
+
1: http://mech.spbstu.ru/images/b/b0/003.png
if (Key == 27)
+
Доказано, что минимум достигается при:
exit(0);
+
2: http://mech.spbstu.ru/images/2/20/005.png
// Отрисовка интерполированных графиков
+
записываем пункт 2 в нашу программу, находим коэффициенты и находим значение линейной функции y=ax+b, по интерполированным значениям x.
else if ((Key == 'G') || (Key == 'g'))
 
IsGraph = !IsGraph;
 
// Сохранение графика суммы в файл
 
else if ((Key == 'S') || (Key == 's'))
 
IsSave = !IsSave;
 
// Загрузка графика из файла
 
else if ((Key == 'L') || (Key == 'l'))
 
IsLoad = !IsLoad;
 
// Открытие программы в полном экране
 
else if ((Key == 'F') || (Key == 'f'))
 
glutFullScreen();
 
} /* End of 'Keyboard' function */
 
  
/* Main function */
 
int main( int argc, char *argv[] )
 
{
 
// Инициализации OpenGL и GLUT
 
glutInit(&argc, argv);
 
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
 
  
// Задача размеров и позиции окна
+
<div class="mw-collapsible-content">
glutInitWindowPosition(0, 0);
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
glutInitWindowSize(500, 500);
 
// Создание окна
 
glutCreateWindow("T05GRAPH");
 
  
// Установка функций 'обратного вызова'
+
#include <iostream>
glutDisplayFunc(Display);
+
#include <math.h>
glutKeyboardFunc(Keyboard);
+
#include <iomanip>
 +
#include<stdlib.h>
 +
using namespace std;
  
// Запускаем основной цикл построения
+
class func
glutMainLoop();
+
{
return 0;
+
private:
} /* End of 'main' function */
+
    double a/*начало*/,b/*конец*/,c/*шаг*/,k/**/,m/**/,rr/**/;
 +
    int d/*переменная для изменения типа, кол-во элементов для начальных элементов*/,tt/*переменная для изиенения типа, кол-ва элементов для счёта суммы*/;
 +
    double *F/*массив для значений У*/, *X/*Массив для значений Х*/, *R/*массив для значений У после интерполяции*/, *Q;
 +
public:
  
/* END OF 'T05GRAPH.CPP' FILE */
+
    func (double a1, double b1, double c1):a(a1),b(b1),c(c1)//создаём конструктор для функции
</syntaxhighlight>
+
    {
"'''GRAPH.CPP'''"
+
        double p = (b-a)/c;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
        d = (int)p;
/* FILENAME: GRAPH.CPP
+
        if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
* LAST UPDATE: 17.01.2016
+
        else d += 1;
*/
 
  
#include "GRAPH.H"
+
        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; //присваивание значений всех Х
  
/* Load Array of points function */
+
    }
// Загрузка графика из файла по точкам
+
    void first ()//функция для первой функции
void graph::LoadArray( char *FileName )
+
    {
{
+
        double y;//в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
// Создание указателя на тип FILE
+
        F[0]=pow(2,a);//объявление значения У для начала промежутка
FILE *F;
+
        F[d-1]=pow(2,b);//объявление значения У для конца промежутка
 
+
        for(int i = 1; i < d-1; ++i)
// Создание файла и открытие его в режиме чтения
+
        {
fopen_s(&F, FileName, "rt");
+
            y = pow(2,((c*i)+a));//высчитываем значения У внутри промежутка
 +
            F[i] = y;//присваиваем массиву значения по У
 +
        }
  
// Количество точек
+
        cout << " " << endl;//пробел и конец строки
fscanf(F, "%d", &N);
+
    }
// Шаг функции
 
fscanf(F, "%lf", &Step);
 
// Начальная координата по X
 
fscanf(F, "%lf", &MinX);
 
// Конечная координата по X
 
fscanf(F, "%lf", &MaxX);
 
 
// Выделение памяти под массив точек
 
mas = new vec[N];
 
  
// Заполнение массива точек из файла
+
    void second ()//функция для второй функции
for (int i = 0; i < N; ++i)
+
    {
{
+
        if(a==0 || b==0) return;
// Заполнение по X
+
        F[0]=1*a*a; //присваивание значения функции в начале промежутка
fscanf(F, "%lf", &mas[i].X);
+
        F[d-1]=1*b*b;//присваивание значения функции в конце промежутка
// Заполнение по Y
 
fscanf(F, "%lf", &mas[i].Y);
 
}
 
  
// Закрытие файла
+
        for(int k = 1; k <d-1; ++k)
fclose(F);
+
        {
} /* End of 'LoadArray' function */
+
            double n = c*k+a;
 +
            if (n != 0)//условие неделимости на ноль
 +
            {
 +
                F[k] = 1*n*n;
 +
            }
 +
        }
  
/* Fill mas function */
+
    }
// Заполнение массива координат точек с цветом
 
void graph::Fill( double(*f)(double) )
 
{
 
// Выделение памяти под массив точек
 
mas = new vec[N];
 
// Выделение памяти под массив цветов
 
Color = new vec[N];
 
  
// Заполнение массивов
+
    void operator +(func Q)//перегрузка оператора +
for (int i = 0; i < N; i++)
+
    {
{
+
        sum(Q);
mas[i] = vec(MinX + i * Step, f(MinX + i * Step));
+
    }
Color[i] = vec::Rnd();
 
}
 
} /* End of 'Fill' function */
 
  
/* Draw graph function */
+
    void sum (func Q)//функция суммирования функций на интерполированном шаге
// Рисование заполненного графика на экран
+
    {  double m, p = (b-a)/c;
void graph::Draw( void )
+
    int i;
{
+
        R=new double[d+2];
  // Задача размер точки
+
          if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
glPointSize(1);
+
        else d += 1;
// Рисование
+
    m=a;
glBegin(GL_POINTS);
+
cerr<<"\n";
for (int i = 0; i < N; i++)
+
 
glVertex2d(mas[i].X, mas[i].Y);
+
        for(i = 0; i <d-1; ++i)//цикл суммирования функций и вывода значений суммы, функций и иксов
glEnd();
+
        {
} /* End of 'Draw' function */
 
  
/* Draw graph function */
+
            cerr <<"YFirst: "<< F[i] << "  ";
// Рисование не заполненного еще графика на экран
+
            cerr << "YSecond: "<< Q.F[i] << "  ";
void graph::Draw( double(*f)(double) )
+
            R[i] = F[i] + Q.F[i];
{
+
            cerr << "Ysum: "<< R[i] << "  ";
// Заполнение массива
+
            cerr << "X:" << m << '\n';
graph::Fill(f);
 
  
// Задача цвета и размера точки
+
            m=m+c;
glColor3d(0, 0, 0);
+
        }
glPointSize(1);
+
  for(i = 0; i <d-1; ++i)
// Рисование
+
        {Q.F[i]=R[i];
glBegin(GL_POINTS);
+
}
for (int i = 0; i < N; i++)
+
        cerr << " " << endl;
glVertex2d(mas[i].X, mas[i].Y);
+
    }
glEnd();
 
} /* End of 'Draw' function */
 
  
/* Interpolation draw graph function */
+
double interp( double pnt/*новый шаг*/, func Q)//функция для интерполяции функции
// Рисование интерполированного графика на экран
+
    {double p,h,i,w,*X,aApr,bApr,X2sm,XYsm,Xsm/*хранит сумму интерполированных иксов*/,Ysm/*хранит сумму интерполированных игреков*/;
void graph::Interpolation_Draw( double i_step )
+
    int q,k,l,o;
{
+
    p=(b-a)/pnt+1;
// Коэффициент Катмулл-Рома
+
    q=int(p);
double alpha = 1.0 / 6;
+
    R=new double [q];
+
    X=new double [q];
// Кубическая интерполяция кривыми Безье
 
for (int i = 0; i < N - 1; i++)
 
{
 
// Создание 4 точек для интерполяции по ним
 
vec P0 = mas[i], P1, P2, P3 = mas[i + 1];
 
vec Color0 = mas[i], Color1, Color2, Color3 = mas[i + 1];
 
  
// Значения для первого и последнего отрезков
+
    l=0;
if (i == 0)
+
    k=0;
{
 
P1 = (mas[1] - mas[0]) * alpha + mas[0];
 
Color1 = (mas[1] - mas[0]) * alpha + mas[0];
 
}
 
else
 
{
 
P1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
 
Color1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
 
}
 
if (i == N - 2)
 
{
 
P2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
 
Color2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
 
}
 
else
 
{
 
P2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
 
Color2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
 
}
 
  
glLineWidth(2);
+
    for(h=a/*начало функции*/; h<=b/*конец функции*/; h=h+c/*старый шаг*/) //шагает по нормальному шагу
glBegin(GL_LINE_STRIP);
+
    {
for (double t = 0; t <= 1; t += i_step)
+
        for(i=a-1; i<=b; i=i+pnt/*новый шаг*/)
{
+
          if((i>h)&&(i<=(h+c)))//проверяет лежит ли новый шаг между точками старого
vec p, color;
+
            {  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;
  
// Вычисление точки интерполированного графика по 4 точкам
+
    for(o=0;o<=k;o++)//цикл подготавливает суммы для МНК
p = P0 * (1 - t) * (1 - t) * (1 - t) + P1 * 3 * (1 - t) * (1 - t) * t + P2 * 3 * (1 - t) * t * t + P3 * t * t * t;
+
        {Xsm+=X[o];
color = Color0 * (1 - t) * (1 - t) * (1 - t) + Color1 * 3 * (1 - t) * (1 - t) * t + Color2 * 3 * (1 - t) * t * t + Color3 * t * t * t;
+
        Ysm+=R[o];
 +
        XYsm+=X[o]*R[o];
 +
        X2sm+=X[o]*X[o];
 +
        }
  
// Рисование
+
aApr=(k*XYsm-Xsm*Ysm)/(k*X2sm-Xsm*Xsm);//находим коэфициенты по МНК
glColor3d(color.X / 10, 0, color.Y);
+
bApr=(Ysm-a*Xsm)/k;
glVertex2d(p.X, p.Y);
+
cout<<"\n"<<"aAprox"<<a<<"  "<<"bAprox"<<b<<"\n";//выводим их
}
+
for(o=0;o<k;o++)
glEnd();
+
        {c=aApr*X[o]+bApr;//считаем значение Y при данных коэфициентах
}
+
        cout<<"YAprox: "<<c<<" "<<"X:"<<X[o]<<"\n" ;
} /* End of 'Interpolation_Draw' function */
+
        }
  
/* Interpolation graph function */
 
// Интерполяция графика
 
graph graph::Interpolation( double i_step )
 
{
 
graph G_New;
 
// Коэффициент Катмулл-Рома
 
double alpha = 1.0 / 6;
 
  
// Заполнение параметров для нового графика
+
    return 0;}
G_New.MinX = MinX;
+
};
G_New.MaxX = MaxX;
 
G_New.Step = Step * i_step;
 
G_New.N = (int)((G_New.MaxX - G_New.MinX) / G_New.Step);
 
G_New.mas = new vec[G_New.N];
 
 
// Кубическая интерполяция кривыми Безье
 
for (int i = 0; i < N - 1; i++)
 
{
 
// Создание 4 точек для интерполяции по ним
 
vec P0 = mas[i], P1, P2, P3 = mas[i + 1];
 
 
// Значения для первого и последнего отрезков
 
if (i == 0)
 
P1 = (mas[1] - mas[0]) * alpha + mas[0];
 
else
 
P1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
 
if (i == N - 2)
 
P2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
 
else
 
P2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
 
 
for (double t = 0; t <= 1; t += i_step)
 
{
 
vec p;
 
  
// Вычисление точки интерполированного графика по 4 точкам
+
int main(){
G_New.mas[(int)((t + i) / i_step)] = P0 * (1 - t) * (1 - t) * (1 - t) + P1 * 3 * (1 - t) * (1 - t) * t + P2 * 3 * (1 - t) * t * t + P3 * t * t * t;
+
    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 G_New;
+
return 0;}
} /* End of 'Interpolation' function */
+
</syntaxhighlight>
 +
</div>
  
/* Sum of 2 graphics function */
 
// Сложение двух графиков
 
graph graph::operator+( graph &G )
 
{
 
graph G_New, G1, G2;
 
int i, j;
 
  
// Заполнение параметров графика суммы
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
G_New.MinX = (MinX >= G.MinX) ? MinX : G.MinX;
+
'''[[Рубинова Раиса]]'''
G_New.MaxX = (MaxX <= G.MaxX) ? MaxX : G.MaxX;
 
G_New.Step = Step * G.Step;
 
G_New.N = (int)((G_New.MaxX - G_New.MinX) / G_New.Step);
 
G_New.mas = new vec[G_New.N];
 
  
// Интерполяция слагаемых графиков, для приведение к общему шагу
+
'''Описание программы''': программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции.
G1 = Interpolation(G.Step);
 
G2 = G.Interpolation(Step);
 
  
// Поиск общего начала и конца графиков
+
'''Инструкция к программе''':
for (i = 0; i < G1.N; i++)
+
1. Пользователь вводит параметры первой функции
if (fabs(G1.mas[i].X - G_New.MinX) <= Threshold)
+
2. Пользователь вводит параметры второй функции (при этом шаг второй функции меньше шага первой)
break;
+
3. Происходит интерполяция первой функции по второй
 +
4. Пользователь выбирает арифметическую операцию
 +
5. При желании пользователь может выполнить аппроксимацию полученного результата
  
for (j = 0; j < G2.N; j++)
 
if (fabs(G2.mas[j].X - G_New.MinX) <= Threshold)
 
break;
 
  
// Заполнение графика суммы
+
Скачать можно [http://tm.spbstu.ru/File:Funcc.rar тут].
for (int k = 0; k < G_New.N; k++)
 
{
 
G_New.mas[k].X = G_New.MinX + k * G_New.Step;
 
G_New.mas[k].Y = G1.mas[i + k].Y + G2.mas[j + k].Y;
 
}
 
  
return G_New;
 
} /* End of 'Sum' function */
 
  
/* Save Array of points function */
+
<div class="mw-collapsible-content">
// Сохранение графика в файл по точкам
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
void graph::SaveArray( void )
+
#ifndef FUNC_H
{
+
#define FUNC_H
// Создание указателя на тип FILE
 
FILE *F;
 
  
// Создание файла и открытие его в режиме записи
 
fopen_s(&F, "graph.txt", "wt");
 
  
/* Запись в файл данных */
+
class Func
// Количество точек
+
{
fprintf(F, "%d\n", N);
+
    public:
// Шаг функции
+
        Func(double a1, double b1, double c1);
fprintf(F, "%lf\n", Step);
+
        virtual ~Func();
// Начальная координата по X
+
        void DefFunc ();    // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
fprintf(F, "%lf\n", MinX);
+
        void PluFunc (Func D);  // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
// Конечная координата по X
+
        void operator +(Func D); // перегрузка оператора '+'
fprintf(F, "%lf\n", MaxX);
+
        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 (); // Функция вывода на экран значений
 +
    protected:
 +
    private:
 +
        double a,b,c;
 +
        int j,z;
 +
        double *A,*B;
 +
};
 +
 
 +
#endif // FUNC_H
  
// Координаты всех точек
 
for (int i = 0; i < N; ++i)
 
  fprintf(F, "%lf %lf ", mas[i].X, mas[i].Y);
 
  
// Закрытие файла
 
fclose(F);
 
} /* End of 'SaveArray' function */
 
  
/* Approximation of function function */
+
#include "Func.h"
// Аппроксимация графика
+
#include <fstream>
void graph::Approximation( void )
+
#include <iostream>
{
+
#include <math.h>
double k, b, s1 = 0, s2 = 0, s3 = 0, s4 = 0;
 
  
// Линейная аппроксимация
+
Func::Func(double a1, double b1, double c1):a(a1),b(b1),c(c1)   // конструктор для класса Func, создающий объект данного класса, определенный тремя значениями, введенными пользователем
for (int i = 0; i < N; i++)
+
{
{
+
    double d=(b-a)/c;   // расчет количества элементов, определяющих функцию
if (fabs(mas[i].X) < MAX && fabs(mas[i].Y) < MAX)
+
    j=floor(d);   // созданной целочисленной переменной присваивается значение, равное целой части числа, рассчитанного выше, с округлением в меньшую сторону
{
+
    A = new double [j+1];   // создание массива
s1 += mas[i].X * mas[i].Y;
+
}
s2 += mas[i].X;
 
s3 += mas[i].X * mas[i].X;
 
s4 += mas[i].Y;
 
}
 
}
 
  
k = (N * s1 - s2 * s4) / (double(N) * s3 - s2 * s2);
+
Func::~Func()   // деструктор для класса Func
b = (s4 - k * s2) / double(N);
+
{
 +
    //dtor
 +
}
  
// Задача цвета и ширины линии
+
void Func::Viv ()  // Функция вывода на экран значений
glColor3d(1, 0.5, 0);
+
{
glLineWidth(1);
+
    std::cout << "x ";
// Рисование
+
    for (int z=0; z<=j; ++z)
glBegin(GL_LINE_STRIP);
+
    {
glVertex2d(MinX, MinX * k + b);
+
        std::cout << z+1 << " ";
glVertex2d(MaxX, MaxX * k + b);
+
    }
glEnd();
+
}
} /* End of 'Approximation' function */
 
  
/* End of 'GRAPH.CPP' file */
+
void Func::DefFunc ()  // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
</syntaxhighlight>
+
{
"'''GRAPH.H'''"
+
    double x;  // создание переменной, используемой для расчета значений функции
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    for(int i=0; i<=j; ++i) // создание цикла, рассчитывающего j элементов
/* FILENAME: GRAPH.H
+
    {
* LAST UPDATE: 17.01.2016
+
        x =i*c+a;  // задание значения перемнной x, определенной выше
*/
+
        A[i]=x*x;  // задание значения самой функции (при этом в данной ситуации нам неважно, как именно задается функция, ее значения могут быть определены любым способом, от этого алгоритм не меняется)
 +
        std::cerr << A[i] << " ";  // вывод на экран значения функции
 +
    }
 +
}
  
#ifndef _GRAPH_H_
+
void Func::PluFunc (Func D)  // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
#define _GRAPH_H_
 
 
 
#define _CRT_SECURE_NO_WARNINGS
 
 
 
#include <iostream>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <math.h>
 
#include <time.h>
 
#include <GL\glut.h>
 
 
 
#define MAX 100
 
 
 
using namespace std;
 
 
 
/* Useful constants */
 
const double Threshold = 1e-10;
 
const double Infinity = 1e+10;
 
 
 
/* Vector representation type */
 
class vec
 
 
{
 
{
public:
+
    std::ofstream out("zap.txt");  // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
double X, Y;
+
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
 
+
    {
/* Default constructor */
+
        B[i]=B[i]+D.A[i];  // сложение значений двух функций для одного и того же значения переменной
vec( void )
+
    }
{
+
    for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
}
+
    {
 
+
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
/* Class constructor */
+
    }
vec( double A ) : X(A), Y(A)
+
    out.close();    // закрытие файла после записи в него значений
{
+
    D.Viv();
}
+
    std::cout << std::endl << "y ";
 
+
    for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран
/* Class constructor */
+
    {
vec( double A, double B ) : X(A), Y(B)
+
        std::cout << B[i] << " ";
{
+
    }
}
+
}
 
+
void Func::operator +(Func D)   // перегрузка оператора '+'
static double R0( void )
+
{
{
+
    PluFunc(D);                        // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1+f2 будет работать аналогично записи f1.PluFunc(f2)
return rand() / (double)RAND_MAX;
+
}
} /* End of 'R0' function */
+
void Func::MinFunc (Func D)    // функция, линейно вычитающая значения второй функции из значений первой функции
 
+
{
static vec Rnd( void )
+
    std::ofstream out("zap.txt");  // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
{
+
    for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
return vec(R0(), R0());
+
    {
} /* End of 'Rnd' function */
+
        B[i]=B[i]-D.A[i];   // вычитание значений второй функций из значений первой для одного и того же значения переменной
 
+
    }
/* The functions of operations on vectors */
+
    for (int i=0; i<=D.j; ++i)  // создание цикла, рассчитанного на то же количество раз, что и предыдущий
 
+
    {
/* Vector = vector function */
+
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
vec operator=( vec &B )
+
    }
{
+
    out.close();    // закрытие файла после записи в него значений
X = B.X;
+
    D.Viv();
Y = B.Y;
+
    std::cout << std::endl << "y ";
 
+
    for (int i=0; i<=D.j; ++i)  // аналогичный предыдущему цикл, выводящий значения на экран
return B;
+
    {
} /* end of 'operator+' function */
+
        std::cout << B[i] << " ";
 
+
    }
/* Vector add vector function */
+
}
vec operator+( const vec &B ) const
+
void Func::operator -(Func D)  // перегрузка оператора '-'
{
+
{
return vec(X + B.X, Y + B.Y);
+
    MinFunc(D);    // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1-f2 будет работать аналогично записи f1.MinFunc(f2)
} /* end of 'operator+' function */
+
}
 
+
void Func::UmnFunc (Func D)     // функция, линейно переумножающая значения функций
/* Vector sub vector function */
+
{
vec operator-( const vec &B ) const
+
    std::ofstream out("zap.txt");    // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
{
+
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
return vec(X - B.X, Y - B.Y);
+
    {
} /* end of 'operator-' function */
+
        B[i]=B[i]*D.A[i];   // умножение значений первой функций на значенийя второй для одного и того же значения переменной
 
+
    }
vec operator-( void ) const
+
    for (int i=0; i<=D.j; ++i)    // создание цикла, рассчитанного на то же количество раз, что и предыдущий
{
+
    {
return vec(-X, -Y);
+
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
} /* end of 'operator-' function */
+
    }
 
+
    out.close();    // закрытие файла после записи в него значений
/* Vector mul number function */
+
    D.Viv();
vec operator*( const double N ) const
+
    std::cout << std::endl << "y ";
{
+
    for (int i=0; i<=D.j; ++i)  // аналогичный предыдущему цикл, выводящий значения на экран
return vec(X * N, Y * N);
+
    {
} /* end of 'operator*' function */
+
        std::cout << B[i] << " ";
 
+
    }
/* Vector div number function */
+
}
vec operator/( const double N ) const
+
void Func::operator *(Func D)   // перегрузка оператора '*'
{
+
{
return vec(X / N, Y / N);
+
    UmnFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1*f2 будет работать аналогично записи f1.UmnFunc(f2)
} /* end of 'operator/' function */
+
}
 
+
void Func::DelFunc (Func D)    // функция, линейно делящая значения первой функци на значения второй функции
/* Vector dot vector function */
+
{
double operator&( const vec &B ) const
+
    std::ofstream out("zap.txt");  // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
{
+
    for(int i=0; i<=D.j; ++i)    // создание цикла, повторяющегося (D.j+1) раз
return double(X * B.X + Y * B.Y);
+
    {
} /* end of 'operator&' function */
+
        B[i]=B[i]/D.A[i];       // деление значений первой функций на значенийя второй для одного и того же значения переменной
 
+
    }
vec & operator+=( const vec &B )
+
    for (int i=0; i<=D.j; ++i)      // создание цикла, рассчитанного на то же количество раз, что и предыдущий
{
+
    {
X += B.X;
+
        out << B[i] << '\n';        // запись значений, полученных в предыдущем цикле, в файл
Y += B.Y;
+
    }
 
+
    out.close();    // закрытие файла после записи в него значений
return *this;
+
    D.Viv();
} /* end of 'operator+=' function */
+
    std::cout << std::endl << "y ";
 
+
    for (int i=0; i<=D.j; ++i)      // аналогичный предыдущему цикл, выводящий значения на экран
vec & operator-=( const vec &B )
+
    {
{
+
        std::cout << B[i] << " ";
X -= B.X;
+
    }
Y -= B.Y;
+
}
 
+
void Func::operator /(Func D)  // перегрузка оператора '/'
return *this;
+
{
} /* end of 'operator-=' function */
+
    DelFunc(D);    // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1/f2 будет работать аналогично записи f1.DelFunc(f2)
 
+
}
vec & operator*=( const double N )
+
void Func::In (Func D)     // функция, интерполирующая первую функцию по второй
{
+
{
X *= N;
+
    double l=c/D.c;    // создаем переменную, которой присваиваем значение, обозначающее, во сколько раз один шаг больше другого
Y *= N;
+
    c=D.c;      // приводим больший шаг к меньшему значению
 
+
    z=D.j+1;    // ранее созданной переменной присваиваем значение, равное количеству элементов плюс один
return *this;
+
    int p=l;    // создаем целочисленную переменную, равную переменной l
} /* end of 'operator*=' function */
+
    B = new double [D.j+2];    // создание массива с количеством элементов D.j+2
 
+
    D.Viv(); std::cout << std::endl << "y ";
vec & operator/=( const double N )
+
    B[0]=A[0]; std::cerr << B[0] << " ";    // присваиваем первому элементу нового массива значение первого элемента старого массива и выводим его на экран
{
+
    int k=0;    // создаем вспомогательную целочисленную переменную
X /= N;
+
    for (int i=0; i<=j; i+=p)  // создаем цикл, рассчитанный на j повторов через p
Y /= N;
+
    {
 +
        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 на единицу
 +
    }
 +
}
 +
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)    // цикл, который высчитывает сумму всех значений функции
 +
        {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();
 +
}
 +
 
  
return *this;
 
} /* end of 'operator/=' function */
 
  
double operator!( void ) const
+
#include <iostream>
{
+
#include <fstream>
return double(X * X + Y * Y);
+
#include "Func.h"
} /* end of 'operator!' function */
 
  
/* Access vector components by index function */
+
using namespace std;
double operator[]( const int i ) const
+
double m,n,o, m1, n1, o1;
{
+
int a;
switch (i)
+
char b;
{
 
case 0:
 
return double(X);
 
case 1:
 
return double(Y);
 
}
 
} /* end of 'operator[]' function */
 
  
/* Normalizing vector function */
+
int main()
vec & Normalize( void )
 
{
 
double len = !*this;
 
 
 
if (len != 1 && len != 0)
 
*this /= sqrt(len);
 
return *this;
 
} /* end of 'Normalize' function */
 
}; /* end of 'vec' class */
 
 
 
/* Graph class */
 
class graph
 
 
{
 
{
public:
+
    cout << "Enter the beginning, the end and the step of a function." << endl; // ввод опорных значений первой функции: начало, конец, шаг;
double MinX, MaxX, Step; // Начальная координата по X; Конечная координата по X; Шаг функции
+
    cin >> m >> n >> o; // считывание значений
int N; // Количество точек
+
    cout << "Enter the beginning, the end and the step of another function." << endl; // ввод опорных значений второй функции: начало, конец, шаг;
vec *mas, *Color; // Массивы точек и цветов
+
    cin >> m1 >> n1 >> o1; // считывание значений
 
+
    Func F(m,n,o); // создание объекта класса Func, определяющий первую функцию
/* Default constructor */
+
    cout << "The first function is" << endl; F.Viv(); cout << endl << "y ";
graph( void )
+
    F.DefFunc(); // определение первой функции через создание массива с ее значениями
{
+
    cout << endl;
MinX = -10, MaxX = 10, Step = 0.1, N = 200;
+
    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;
 +
}
  
/* Class constructor */
+
</syntaxhighlight>
graph( double _MinX, double _MaxX, double _Step ) : MinX(_MinX), MaxX(_MaxX), Step(_Step)
+
</div>
{
 
N = (int)((MaxX - MinX) / Step);
 
// Выделение памяти
 
mas = new vec[N];
 
Color = new vec[N];
 
}
 
  
/* Load Array of points function */
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
void LoadArray( char *FileName );
+
'''[[Савельева Ольга]]'''
 
+
/* Fill mas function */
+
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения.
void Fill( double(*f)(double) );
+
<div class="mw-collapsible-content">
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
//Бибилотека необходимая для возможности включения русского языка в консоли
 +
#include <locale.h>
  
/* Draw graph function */
+
class fun
void Draw( double(*f)(double) );
+
{
 +
/*
 +
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
  
/* Draw graph function */
+
public:
void Draw( void );
+
//Коструктор по умолчанию
 +
fun();
 +
//Конструктор копирования
 +
fun(fun &tmp);
 +
//Деструктор
 +
~fun();
  
/* Interpolation draw graph function */
+
//Перегруженные операторы. Ключевое слово const в конце означает, что объект от которого вызвается метод не изменяется
void Interpolation_Draw( double i_step );
+
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);
  
/* Interpolation graph function */
+
//Метод считывания из файла
graph Interpolation( double i_step );
+
void readFile(const char *path);
 +
//Метод вывода в файл
 +
void writeFile(const char *path);
  
/* Sum of 2 graphics function */
+
//Метод изменения шага
graph operator+( graph &G );
+
void changeDx(double newDx);
 +
//Метод вычисления значения в заданной точке
 +
double getX(double x1);
 +
};
  
/* Save Array of points function */
+
//В конструкторе по умолчанию все просто.
void SaveArray( void );
+
fun::fun()
 +
{
 +
a = b = dx = 0;
 +
fx = NULL;
 +
}
  
/* Approximation of function function */
+
//Конструктор копирования
void Approximation( void );
+
fun::fun(fun &tmp)
}; /* end of 'graph' class */
+
{
 +
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];
 +
}
  
#endif /* _GRAPH_H_ */
+
//Деструктор
 +
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];
  
/* End of 'GRAPH.H' file */
+
//Возвращение результата
</syntaxhighlight>
+
return result;
</div>
+
}
[http://tm.spbstu.ru/File:T05GRAPH.7z Скачать архив]
 
<br>
 
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
//Этот оператор аналогичен оператору сложение
'''[[Рубинова Раиса]]'''
+
const fun fun::operator-(const fun& right) const
 
+
{
'''Описание программы''': программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции.
+
fun result;
 
+
int i, n;
'''Инструкция к программе''':
+
result.dx = dx;
1. Пользователь вводит параметры первой функции
+
result.a = a;
2. Пользователь вводит параметры второй функции (при этом шаг второй функции меньше шага первой)
+
result.b = b;
3. Происходит интерполяция первой функции по второй
+
n = (b - a) / dx + 1;
4. Пользователь выбирает арифметическую операцию
+
result.fx = new double[n];
5. При желании пользователь может выполнить аппроксимацию полученного результата
+
for (i = 0; i<n; ++i)
 +
result.fx[i] = fx[i] - right.fx[i];
  
 +
return result;
 +
}
  
Скачать можно [http://tm.spbstu.ru/File:Funcc.rar тут].
+
//Этот оператор аналогичен оператору сложение
 +
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;
 +
}
  
<div class="mw-collapsible-content">
+
//Этот оператор аналогичен оператору сложение
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
const fun fun::operator/(const fun& right) const
#ifndef FUNC_H
 
#define FUNC_H
 
 
 
 
 
class Func
 
 
{
 
{
    public:
+
fun result;
        Func(double a1, double b1, double c1);
+
int i, n;
        virtual ~Func();
+
result.dx = dx;
        void DefFunc ();    // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
+
result.a = a;
        void PluFunc (Func D); // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
+
result.b = b;
        void operator +(Func D); // перегрузка оператора '+'
+
n = (b - a) / dx + 1;
        void MinFunc (Func D);  // функция, линейно вычитающая значения второй функции из значений первой функции
+
result.fx = new double[n];
        void operator -(Func D); // перегрузка оператора '-'
+
for (i = 0; i<n; ++i)
        void UmnFunc (Func D); // функция, линейно переумножающая значения функций
+
result.fx[i] = fx[i] / right.fx[i];
        void operator *(Func D); // перегрузка оператора '*'
 
        void DelFunc (Func D); // функция, линейно делящая значения первой функци на значения второй функции
 
        void operator /(Func D); // перегрузка оператора '/'
 
        void In (Func D);  // функция, интерполирующая первую функцию по второй
 
        void App (); // функция, аппроксимирующая полученную в результате сложения/вычитания/деления/умножения двух функций функцию
 
        void Viv ();  // Функция вывода на экран значений
 
    protected:
 
    private:
 
        double a,b,c;
 
        int j,z;
 
        double *A,*B;
 
};
 
  
#endif // FUNC_H
+
return result;
 +
}
  
 +
//Оператор присваивания
 +
const fun& fun::operator=(const fun& right)
 +
{
 +
//Проверка на самоприсваивание
 +
if (this == &right)
 +
//Возвращение в качестве результата текущий объект
 +
return *this;
  
  
#include "Func.h"
+
int i, n;
#include <fstream>
+
//Присваивание свойств объекта right текущему объекту
#include <iostream>
+
a = right.a;
#include <math.h>
+
b = right.b;
 +
dx = right.dx;
 +
//Вычисление количества дискретных значений
 +
n = (b - a) / dx + 1;
 +
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
 +
if (fx != NULL) delete[] fx;
 +
//Выделение необходимой памяти для хранения дискретных значений
 +
fx = new double[n];
  
Func::Func(double a1, double b1, double c1):a(a1),b(b1),c(c1)  // конструктор для класса Func, создающий объект данного класса, определенный тремя значениями, введенными пользователем
+
//Копирование дискретных значений объекта right в текущий объект
{
+
for (i = 0; i<n; ++i)
    double d=(b-a)/c;   // расчет количества элементов, определяющих функцию
+
fx[i] = right.fx[i];
    j=floor(d);    // созданной целочисленной переменной присваивается значение, равное целой части числа, рассчитанного выше, с округлением в меньшую сторону
 
    A = new double [j+1];   // создание массива
 
}
 
  
Func::~Func()  // деструктор для класса Func
+
//Возвращение в качестве результата текущий объект
{
+
return *this;
    //dtor
 
 
}
 
}
  
void Func::Viv ()  // Функция вывода на экран значений
+
/*
{
+
Метод считывания из файла
    std::cout << "x ";
+
path - путь к файлу из которого считывать
    for (int z=0; z<=j; ++z)
+
*/
    {
 
        std::cout << z+1 << " ";
 
    }
 
}
 
  
void Func::DefFunc ()   // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
+
void fun::readFile(const char *path)
 
{
 
{
    double x;  // создание переменной, используемой для расчета значений функции
+
//Открытие файла для считывания
    for(int i=0; i<=j; ++i) // создание цикла, рассчитывающего j элементов
+
FILE *in = fopen(path, "r");
    {
+
int i, n;
        x =i*c+a;   // задание значения перемнной x, определенной выше
+
//Считывание границ отрезка и шага из файла
        A[i]=x*x;   // задание значения самой функции (при этом в данной ситуации нам неважно, как именно задается функция, ее значения могут быть определены любым способом, от этого алгоритм не меняется)
+
fscanf(in, "%lf%lf%lf", &a, &b, &dx);
        std::cerr << A[i] << " ";   // вывод на экран значения функции
+
//Вычисление количества дискретных значений
    }
+
n = (b - a) / dx + 1;
 +
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
 +
if (fx != NULL) delete[] fx;
 +
//Выделение необходимой памяти для хранения дискретных значений
 +
fx = new double[n];
 +
//Считывание дискретных значений из файла
 +
for (i = 0; i<n; ++i) fscanf(in, "%lf", &fx[i]);
 +
//Закрытие файла
 +
fclose(in);
 
}
 
}
  
void Func::PluFunc (Func D)  // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
+
/*
 +
Метод вывода в файл
 +
path - путь к файлу в который нужно вывести
 +
*/
 +
 
 +
void fun::writeFile(const char *path)
 
{
 
{
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
//Открытие файла для вывода
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
+
FILE *out = fopen(path, "w");
    {
+
int i, n;
        B[i]=B[i]+D.A[i];  // сложение значений двух функций для одного и того же значения переменной
+
double x = a;
    }
+
//Вычисление количества дискретных значений
    for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
n = (b - a) / dx + 1;
    {
+
//Вывод информации о отрезке и шаге в файл
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
+
fprintf(out, "[%.5lf, %.5lf] dx=%.5lf\n", a, b, dx);
    }
+
//Последовательный вывод пары (точка, значение в точке) в файл
    out.close();   // закрытие файла после записи в него значений
+
for (i = 0; i<n; ++i, x += dx)
    D.Viv();
+
fprintf(out, "x=%.5lf f(x)=%.5lf\n", x, fx[i]);
    std::cout << std::endl << "y ";
+
//Закрытие файла
    for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран
+
fclose(out);
    {
 
        std::cout << B[i] << " ";
 
    }
 
 
}
 
}
void Func::operator +(Func D)   // перегрузка оператора '+'
+
 
 +
/*
 +
Метод изменения величины шага
 +
*/
 +
void fun::changeDx(double newDx)
 
{
 
{
    PluFunc(D);                         // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1+f2 будет работать аналогично записи f1.PluFunc(f2)
+
int i, j, n, newN;
}
+
double *newFx, x, newX, x1, y1, x2, y2, K, B;
void Func::MinFunc (Func D)   // функция, линейно вычитающая значения второй функции из значений первой функции
+
//Вычисление количества старых дискретных значений
{
+
n = (b - a) / dx + 1;
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
//Вычисление количества новых дискретных значений
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
+
newN = (b - a) / newDx + 1;
    {
+
//Выделение памяти под новые дискретные значения
        B[i]=B[i]-D.A[i];  // вычитание значений второй функций из значений первой для одного и того же значения переменной
+
newFx = new double[newN];
    }
+
//Определение первой точки в которой вычисляется новое дискретное значение
    for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
newX = a;
    {
+
//Переменная которая бежит по старым дискретным значениям
        out << B[i] << '\n';   // запись значений, полученных в предыдущем цикле, в файл
+
i = 0;
    }
+
//Определение первой точки в которой вычисляется старое дискретное значение
    out.close();   // закрытие файла после записи в него значений
+
x = a;
    D.Viv();
+
//Цикл для формирования новых дискретных значений
    std::cout << std::endl << "y ";
+
for (j = 0; j<newN; ++j, newX += newDx)
    for (int i=0; i<=D.j; ++i)  // аналогичный предыдущему цикл, выводящий значения на экран
+
{
    {
+
//В цикле находим отрезок где лежит точка в которой нужно вычислить новое дискретное значение
        std::cout << B[i] << " ";
+
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;
 
}
 
}
void Func::operator -(Func D)   // перегрузка оператора '-'
+
 
 +
/*
 +
Метод вычисляет значение в точке xAns с помощью линейной интерполяции.
 +
*/
 +
double fun::getX(double xAns)
 
{
 
{
    MinFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1-f2 будет работать аналогично записи f1.MinFunc(f2)
+
int i, n;
 +
double x, x1, y1, x2, y2, K, B;
 +
x = a;
 +
//Вычисление количества дискретных значений
 +
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;
 +
}
 +
}
 
}
 
}
void Func::UmnFunc (Func D)     // функция, линейно переумножающая значения функций
+
 
 +
int main()
 
{
 
{
    std::ofstream out("zap.txt");    // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
//Включение поддержки русского языка в консоли
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
+
setlocale(LC_ALL, "Russian");
    {
+
//Объявление трех переменных типа fun
        B[i]=B[i]*D.A[i];  // умножение значений первой функций на значенийя второй для одного и того же значения переменной
+
fun a, b, c;
    }
+
//Считывания первых дискретных значений из файла inputA.txt
    for (int i=0; i<=D.j; ++i)    // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
a.readFile("inputA.txt");
    {
+
//Считывания вторых дискретных значений из файла inputB.txt
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
+
b.readFile("inputB.txt");
    }
+
 
    out.close();   // закрытие файла после записи в него значений
+
//Первая функция
    D.Viv();
+
a.writeFile("outputA.txt");
    std::cout << std::endl << "y ";
+
//Вторая функция
    for (int i=0; i<=D.j; ++i)  // аналогичный предыдущему цикл, выводящий значения на экран
+
b.writeFile("outputB.txt");
    {
+
 
        std::cout << B[i] << " ";
+
c = a + b;
    }
+
//Результат сложения двух функций
}
+
c.writeFile("outputAaddB.txt");
void Func::operator *(Func D)  // перегрузка оператора '*'
+
 
{
+
 
    UmnFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1*f2 будет работать аналогично записи f1.UmnFunc(f2)
+
c = a - b;
}
+
//Результат вычитания второй функции из первой
void Func::DelFunc (Func D)    // функция, линейно делящая значения первой функци на значения второй функции
+
c.writeFile("outputAsubB.txt");
{
+
 
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
c = a*b;
    for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
+
//Результат умножения двух функций
    {
+
c.writeFile("outputAmultiB.txt");
        B[i]=B[i]/D.A[i];       // деление значений первой функций на значенийя второй для одного и того же значения переменной
+
 
    }
+
c = a / b;
    for (int i=0; i<=D.j; ++i)      // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
//Результат деления первой функции на вторую
    {
+
c.writeFile("outputAdivB.txt");
        out << B[i] << '\n';       // запись значений, полученных в предыдущем цикле, в файл
+
 
    }
+
//У первой функции изменили шаг на 0.5
    out.close();    // закрытие файла после записи в него значений
+
a.changeDx(0.5);
    D.Viv();
+
//Вывели её дискретные значения
    std::cout << std::endl << "y ";
+
a.writeFile("outputChangeDx.txt");
    for (int i=0; i<=D.j; ++i)     // аналогичный предыдущему цикл, выводящий значения на экран
+
 
    {
+
//Функция, которая аппроксимирует её кусочно линейная.
        std::cout << B[i] << " ";
+
//Для примера нашли значение аппроксимируещей функции в точке не совпадающей с дискретными значениями.
    }
+
printf("Значение в точке 1.8 первой функции %.5lf\n", a.getX(1.8));
}
+
 
void Func::operator /(Func D)  // перегрузка оператора '/'
+
//Нужно чтобы окно консоли автоматически не закрылось
{
+
system("pause");
    DelFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1/f2 будет работать аналогично записи f1.DelFunc(f2)
+
return 0;
}
 
void Func::In (Func D)      // функция, интерполирующая первую функцию по второй
 
{
 
    double l=c/D.c;    // создаем переменную, которой присваиваем значение, обозначающее, во сколько раз один шаг больше другого
 
    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 на единицу
 
    }
 
}
 
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)    // цикл, который высчитывает сумму всех значений функции
 
        {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();
 
 
}
 
}
 +
</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 <iostream>
 +
#include <vector>
 +
#include <math.h>
 
#include <fstream>
 
#include <fstream>
#include "Func.h"
+
#include <stdio.h>
 +
#include <string>
 +
#include <time.h>
  
 
using namespace std;
 
using namespace std;
double m,n,o, m1, n1, o1;
 
int a;
 
char b;
 
  
int main()
+
class func {
{
+
     vector <double> vals;
     cout << "Enter the beginning, the end and the step of a function." << endl; // ввод опорных значений первой функции: начало, конец, шаг;
+
    double a, b, step, sz;
    cin >> m >> n >> o; // считывание значений
+
 
    cout << "Enter the beginning, the end and the step of another function." << endl; // ввод опорных значений второй функции: начало, конец, шаг;
+
public:
    cin >> m1 >> n1 >> o1; // считывание значений
+
    func (string fil) { //конструктор для ввода функции из файла
    Func F(m,n,o); // создание объекта класса Func, определяющий первую функцию
+
        ifstream f(fil.c_str());
    cout << "The first function is" << endl; F.Viv(); cout << endl << "y ";
+
        double a, b, step, y;
     F.DefFunc(); // определение первой функции через создание массива с ее значениями
+
        f >> a >> b >> step; //вводим основные значения из файла
     cout << endl;
+
        this->step = step;
    Func F1(m1,n1,o1); // создание объекта класса Func, определяющий вторую функцию
+
        this->sz = (int)((b - a) / step + 1); //считаем размер
    cout << "The second function is" << endl; F1.Viv(); cout << endl << "y ";
+
        this->a = a, this->b = b;
    F1.DefFunc(); // определение второй функции через создание массива с ее значениями
+
        for (int i = 0; i < this->sz; i++) {
    cout << endl;
+
            f >> y;
    cout << "As two functions have different steps, we made the interpolation of the first function." << endl;
+
            this->vals.push_back(y); //считываем и записываем значения из файла
    F.In(F1); // линейная интерполяция первой функции по второй
+
        }
    cout << endl;
+
        f.close();
    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;
+
    func () {} //еще один конструктор
     if (a==1)
+
     func operator + (func a) { // эта и ближайшие четыре метода -- калькулятор функций
    {cout << "Function 1 + function 2 =" << '\n'; F+F1;}   // сложение двух функций с одинаковым шагом и интервалом
+
        func f = *new func(); //создаем новый экземпляр класса, ответ
    else if (a==2)
+
        for (int i = 0; i < sz; i++) {
    {cout << "Function 1 - function 2 =" << '\n'; F-F1;}   // вычитание двух функций с одинаковым шагом и интервалом
+
            f.vals.push_back(this->vals[i] + a.vals[i]); // складываем покоординатно
     else if (a==3)
+
        }
    {cout << "Function 1 * function 2 =" << '\n'; F*F1;}   // умножение двух функций с одинаковым шагом и интервалом
+
        f.step = a.step; // копируем все значения в ответ (возможно, это можно сделать гораздо проще и не писать 4*4 строк но почему-то ничего умнее я не придумал)
    else if (a==4)
+
        f.a = a.a;
    {cout << "Function 1 / function 2 =" << '\n'; F/F1;}   // деление двух функций с одинаковым шагом и интервалом
+
        f.b = a.b;
    cout << endl;
+
        f.sz = a.sz;
    cout << "Enter 5 to do the approximation of the result function" << endl;   // пользователь сам выбирает, выполнять ли аппроксимацию;
+
        return f;
    cout << "Otherwise enter 6 to quit" << endl;
+
     }
    cin >> a;
+
     func operator - (func a) {
    if (a==5)
+
        func f = *new func();
    {cout << "Appromaximation:" << endl;
+
        for (int i = 0; i < a.sz; i++) {
    F.App();}  // аппроксимация
+
            f.vals.push_back(this->vals[i] - a.vals[i]);
    return 0;
+
        }
}
+
        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;
 +
    }
  
</syntaxhighlight>
+
    pair<double, double> approx() { //аппроксимация. это все из наших лаб по физике, тут сплошная математика, никакого программирования
</div>
+
        double mid = 0;
 
+
        for (int i = 0; i < this->sz; i++) {
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
            mid += this->a + i * this->step;
'''[[Савельева Ольга]]'''
+
        }
+
        mid /= this->sz;
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения.
+
        double d = 0;
<div class="mw-collapsible-content">
+
        for (int i = 0; i < this->sz; i++) {
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
            d += pow((this->a + i * this->step - mid), 2.);
#include <stdio.h>
+
        }
#include <stdlib.h>
+
        double a = 0;
//Бибилотека необходимая для возможности включения русского языка в консоли
+
        for (int i = 0; i < this->sz; i++) {
#include <locale.h>
+
            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
 +
    }
  
class fun
+
    func inter(double step) {
{
+
        func f = *new func(); //ответ
/*
+
        double curr2, curr1;
fx - массив с дискретными значениями функции
+
        int j = 0;
a - начало отрезка определения функции
+
        f.a = this->a, f.b = this->b, f.step = step, f.sz = (int)((b - a) / step + 1);
b - конец отрезка определения функции
+
        for (int i = 0; i < f.sz; i++) {
dx - шаг
+
            curr2 = a + i * step;
*/
+
            curr1 = a + j * this->step;
double *fx, a, b, dx;
+
            while (curr1 + this->step <= curr2) {
//Чтобы очусть ошибки округления в вещественных числах при сравнениях используется константа eps.
+
                j++, curr1 += this->step;
//К примеру два вещественных числа x и y сравниваются не так x>=y, а так x-y>=-eps.
+
            }
const double eps = 1e-10; //1e-10 это тоже самое что 0.0000000001
+
            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;
 +
    }
 +
    void write(string fil) { //запись. чтобы записать не в файл, а в консоль вывести, надо передать "-1"
 +
        ofstream f(fil.c_str());
 +
        if (fil != "-1") {
 +
            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';
 +
        }
 +
        f.close();
  
public:
+
    }
//Коструктор по умолчанию
+
};
fun();
 
//Конструктор копирования
 
fun(fun &tmp);
 
//Деструктор
 
~fun();
 
  
//Перегруженные операторы. Ключевое слово const в конце означает, что объект от которого вызвается метод не изменяется
+
int main() {
const fun operator+(const fun& right) const;
+
    string fil;
const fun operator-(const fun& right) const;
+
    cout << "Input the file name with the function values\n";
const fun operator*(const fun& right) const;
+
    cin >> fil;
const fun operator/(const fun& right) const;
+
    func f = *new func(fil);
const fun& operator=(const fun& right);
+
    int a;
 
+
    char ch;
//Метод считывания из файла
+
    double st;
void readFile(const char *path);
+
    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";
void writeFile(const char *path);
+
        cin >> a;
 
+
        if (a == 4) {
//Метод изменения шага
+
            cout << "input file name to write to\n";
void changeDx(double newDx);
+
            cin >> fil;
//Метод вычисления значения в заданной точке
+
            f.write(fil);
double getX(double x1);
+
        }
};
+
        if (a == 3) {
 
+
            auto t = f.approx();
//В конструкторе по умолчанию все просто.
+
            cout << "Approximate line equation is y = " << t.first << " * x + " << t.second << '\n';
fun::fun()
+
        }
{
+
        if (a == 2) {
a = b = dx = 0;
+
            cout << "input step to interpolate\n";
fx = NULL;
+
            cin >> st;
 +
            f = f.inter(st);
 +
        }
 +
        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);
 +
        }
 +
        if (a == 6)
 +
            return 0;
 +
    }
 
}
 
}
 +
</syntaxhighlight>
 +
</div>
  
//Конструктор копирования
 
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];
 
}
 
  
//Деструктор
+
<br>'''[[Нарядчиков Александр]]'''<br>
fun::~fun()
+
'''Инструкция:''' Пользователю достаточно просто запустить программу.<br>
{
+
'''Описание программы:''' В окне рисуются графики с разным шагом, количеством точек, начальными и конечными координатами, по клавише 'G' происходит их кубическая интерполяция, также рисуется график их суммы. По клавише 'S' можно сохранить полученный график в текстовый документ в виде координат его точек. По клавише 'L' можно загрузить график из текстового документа, и он появится в окне программы. Также происходит линейная аппроксимация графика суммы, и график аппроксимации рисуется на экран.<br>
//Освобождение памяти выделенной для массива дискретных значений
+
'''Описание алгоритма:''' Вся графика написана с помощью библиотек OpenGL и GLUT. Кубическая интерполяция написана с помощью кривых Безье(интерполяция по четырем точкам - кубическая кривая). При сложение двух графиков происходит их интерполяция, для приведения их к общему шагу. Линейная аппроксимация написана с помощью метода наименьших квадратов.<br>
if (fx != NULL) delete[] fx;
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
}
+
"'''T05GRAPH.CPP'''"
//Оператор сложения.
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
const fun fun::operator+(const fun& right) const
+
/* FILENAME: T05GRAPH.CPP
{
+
* LAST UPDATE: 17.01.2016
//Создание результирующего объекта
+
*/
fun result;
+
 
int i, n;
+
#include "GRAPH.H"
//Копирование свойств в результирующий объект
 
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;
+
// Глобальная переменная, хранящая время в секундах с момента старта программы
}
+
double SyncTime;
 +
// Глобальные переменные для отслеживания нажатия клавиш
 +
bool IsGraph, IsSave, IsLoad, IsLoaded;
  
//Этот оператор аналогичен оператору сложение
+
/* Timer function */
const fun fun::operator-(const fun& right) const
+
// Подсчет времени
 +
void Timer( void )
 
{
 
{
fun result;
+
long t;
int i, n;
+
static long StartTime = -1;
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;
+
t = clock();
}
+
if (StartTime == -1)
 +
StartTime = t;
 +
SyncTime = (double)(t - StartTime) / CLOCKS_PER_SEC;
 +
} /* End of 'Timer' function */
  
//Этот оператор аналогичен оператору сложение
+
/* Display function */
const fun fun::operator*(const fun& right) const
+
// Стандартная функция, вызываемая при перерисовке окна
 +
void Display( void )
 
{
 
{
fun result;
+
graph G1(-15, 15, 0.1), G2(2, 10, 0.4), G3, G4;
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;
+
// Запуск времени
}
+
Timer();
  
//Этот оператор аналогичен оператору сложение
+
// Установка цвета закраски фона в белый
const fun fun::operator/(const fun& right) const
+
glClearColor(1, 1, 1, 1);
{
+
// Очищаем цветовой буфер для создания нового изображения
fun result;
+
glClear(GL_COLOR_BUFFER_BIT);
int i, n;
+
 
result.dx = dx;
+
glLoadIdentity();
result.a = a;
+
glScaled(0.1 / (1366 / 768.0), 0.1, 0.1);
result.b = b;
+
 
n = (b - a) / dx + 1;
+
// Отрисовка осей X и Y
result.fx = new double[n];
+
glBegin(GL_LINE_STRIP);
for (i = 0; i<n; ++i)
 
result.fx[i] = fx[i] / right.fx[i];
 
  
return result;
+
glColor3d(0, 0, 1);
}
+
glVertex2d(0, -1000);
 +
glVertex2d(0, 1000);
  
//Оператор присваивания
+
glColor3d(1, 0, 0);
const fun& fun::operator=(const fun& right)
+
glVertex2d(-1000, 0);
{
+
glVertex2d(1000, 0);
//Проверка на самоприсваивание
 
if (this == &right)
 
//Возвращение в качестве результата текущий объект
 
return *this;
 
  
 +
glEnd();
  
int i, n;
+
/* Отрисовка графиков */
//Присваивание свойств объекта right текущему объекту
+
// Отрисовка первого графика и его интерполяция по клавише "G"
a = right.a;
+
G1.Draw(sin);
b = right.b;
+
if (IsGraph == 1)
dx = right.dx;
+
G1.Interpolation_Draw(1.0 / 32);
//Вычисление количества дискретных значений
 
n = (b - a) / dx + 1;
 
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
 
if (fx != NULL) delete[] fx;
 
//Выделение необходимой памяти для хранения дискретных значений
 
fx = new double[n];
 
  
//Копирование дискретных значений объекта right в текущий объект
+
// Отрисовка второго графика и его интерполяция по клавише "G"
for (i = 0; i<n; ++i)
+
G2.Draw(log);
fx[i] = right.fx[i];
+
if (IsGraph == 1)
 +
G2.Interpolation_Draw(1.0 / 32);
  
//Возвращение в качестве результата текущий объект
+
// Отрисовка графика суммы для первого и второго графиков
return *this;
+
G3 = G2 + G1;
}
+
glColor3d(0, 1, 0);
 +
G3.Draw();
 +
// Аппроксимация графика суммы
 +
G3.Approximation();
  
/*
+
// Сохранение графика по клавише "S"
Метод считывания из файла
+
if (IsSave == 1)
path - путь к файлу из которого считывать
+
{
*/
+
G3.SaveArray();
 
+
IsSave == 0;
void fun::readFile(const char *path)
+
}
{
+
//Открытие файла для считывания
+
// Загрузка графика по клавише "L"
FILE *in = fopen(path, "r");
+
if (IsLoad == 1)
int i, n;
+
{
//Считывание границ отрезка и шага из файла
+
delete[] G4.mas;
fscanf(in, "%lf%lf%lf", &a, &b, &dx);
+
delete[] G4.Color;
//Вычисление количества дискретных значений
+
G4.LoadArray("graph.txt");
n = (b - a) / dx + 1;
+
IsLoad == 0;
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
+
IsLoaded = 1;
if (fx != NULL) delete[] fx;
+
}
//Выделение необходимой памяти для хранения дискретных значений
+
fx = new double[n];
+
// Отрисовка загруженного графика
//Считывание дискретных значений из файла
+
if (IsLoaded == 1)
for (i = 0; i<n; ++i) fscanf(in, "%lf", &fx[i]);
+
{
//Закрытие файла
+
glColor3d(1, 0, 0);
fclose(in);
+
G4.Draw();
}
+
IsLoaded = 0;
 +
}
  
/*
+
// Чистка памяти
Метод вывода в файл
+
delete[] G1.mas;
path - путь к файлу в который нужно вывести
+
delete[] G1.Color;
*/
+
delete[] G2.mas;
 
+
delete[] G2.Color;
void fun::writeFile(const char *path)
+
delete[] G3.mas;
{
+
delete[] G3.Color;
//Открытие файла для вывода
+
delete[] G4.mas;
FILE *out = fopen(path, "w");
+
delete[] G4.Color;
int i, n;
+
 
double x = a;
+
glFinish();
//Вычисление количества дискретных значений
+
// Копируем вторичный буфер в окно
n = (b - a) / dx + 1;
+
glutSwapBuffers();
//Вывод информации о отрезке и шаге в файл
+
// Вызываем функцию обновления кадра
fprintf(out, "[%.5lf, %.5lf] dx=%.5lf\n", a, b, dx);
+
glutPostRedisplay();
//Последовательный вывод пары (точка, значение в точке) в файл
+
} /* End of 'Display' function */
for (i = 0; i<n; ++i, x += dx)
 
fprintf(out, "x=%.5lf f(x)=%.5lf\n", x, fx[i]);
 
//Закрытие файла
 
fclose(out);
 
}
 
  
/*
+
/* Keyboard function */
Метод изменения величины шага
+
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
*/
+
void Keyboard( unsigned char Key, int X, int Y )
void fun::changeDx(double newDx)
 
 
{
 
{
int i, j, n, newN;
+
// Выход из программы
double *newFx, x, newX, x1, y1, x2, y2, K, B;
+
if (Key == 27)
//Вычисление количества старых дискретных значений
+
exit(0);
n = (b - a) / dx + 1;
+
// Отрисовка интерполированных графиков
//Вычисление количества новых дискретных значений
+
else if ((Key == 'G') || (Key == 'g'))
newN = (b - a) / newDx + 1;
+
IsGraph = !IsGraph;
//Выделение памяти под новые дискретные значения
+
// Сохранение графика суммы в файл
newFx = new double[newN];
+
else if ((Key == 'S') || (Key == 's'))
//Определение первой точки в которой вычисляется новое дискретное значение
+
IsSave = !IsSave;
newX = a;
+
// Загрузка графика из файла
//Переменная которая бежит по старым дискретным значениям
+
else if ((Key == 'L') || (Key == 'l'))
i = 0;
+
IsLoad = !IsLoad;
//Определение первой точки в которой вычисляется старое дискретное значение
+
// Открытие программы в полном экране
x = a;
+
else if ((Key == 'F') || (Key == 'f'))
//Цикл для формирования новых дискретных значений
+
glutFullScreen();
for (j = 0; j<newN; ++j, newX += newDx)
+
} /* End of 'Keyboard' function */
{
+
 
//В цикле находим отрезок где лежит точка в которой нужно вычислить новое дискретное значение
+
/* Main function */
for (; i<n - 1; ++i, x += dx)
+
int main( int argc, char *argv[] )
//Если без eps, то сравнения такие: x<=newX<=x+dx
+
{
if ((newX - x>-eps) && ((x+dx) - newX>-eps))
+
// Инициализации OpenGL и GLUT
{
+
glutInit(&argc, argv);
//Линейная интерполяция
+
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
x1 = x;
+
 
x2 = x + dx;
+
// Задача размеров и позиции окна
y1 = fx[i];
+
glutInitWindowPosition(0, 0);
y2 = fx[i + 1];
+
glutInitWindowSize(500, 500);
K = (y2 - y1) / (x2 - x1);
+
// Создание окна
B = (y2*x1 - y1*x2) / (x1 - x2);
+
glutCreateWindow("T05GRAPH");
//Вычисления значения в точке с помощью линейной интерполяции
+
 
newFx[j] = newX*K + B;
+
// Установка функций 'обратного вызова'
//Выход из цикла по i
+
glutDisplayFunc(Display);
break;
+
glutKeyboardFunc(Keyboard);
}
+
 
}
+
// Запускаем основной цикл построения
//Смена величины шага на новый
+
glutMainLoop();
dx = newDx;
+
return 0;
//Удаление старых дискретных значений
+
} /* End of 'main' function */
delete[] fx;
 
//Присвоение текущему объекту новых дискретных значений
 
fx = newFx;
 
}
 
  
/*
+
/* END OF 'T05GRAPH.CPP' FILE */
Метод вычисляет значение в точке xAns с помощью линейной интерполяции.
+
</syntaxhighlight>
*/
+
"'''GRAPH.CPP'''"
double fun::getX(double xAns)
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
{
+
/* FILENAME: GRAPH.CPP
int i, n;
+
* LAST UPDATE: 17.01.2016
double x, x1, y1, x2, y2, K, B;
+
*/
x = a;
+
 
//Вычисление количества дискретных значений
+
#include "GRAPH.H"
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()
+
/* Load Array of points function */
 +
// Загрузка графика из файла по точкам
 +
void graph::LoadArray( char *FileName )
 
{
 
{
//Включение поддержки русского языка в консоли
+
// Создание указателя на тип FILE
setlocale(LC_ALL, "Russian");
+
FILE *F;
//Объявление трех переменных типа fun
+
 
fun a, b, c;
+
// Создание файла и открытие его в режиме чтения
//Считывания первых дискретных значений из файла inputA.txt
+
fopen_s(&F, FileName, "rt");
a.readFile("inputA.txt");
 
//Считывания вторых дискретных значений из файла inputB.txt
 
b.readFile("inputB.txt");
 
  
//Первая функция
+
// Количество точек
a.writeFile("outputA.txt");
+
fscanf(F, "%d", &N);
//Вторая функция
+
// Шаг функции
b.writeFile("outputB.txt");
+
fscanf(F, "%lf", &Step);
 +
// Начальная координата по X
 +
fscanf(F, "%lf", &MinX);
 +
// Конечная координата по X
 +
fscanf(F, "%lf", &MaxX);
 +
 +
// Выделение памяти под массив точек
 +
mas = new vec[N];
  
c = a + b;
+
// Заполнение массива точек из файла
//Результат сложения двух функций
+
for (int i = 0; i < N; ++i)
c.writeFile("outputAaddB.txt");
+
{
 +
// Заполнение по X
 +
fscanf(F, "%lf", &mas[i].X);
 +
// Заполнение по Y
 +
fscanf(F, "%lf", &mas[i].Y);
 +
}
  
 +
// Закрытие файла
 +
fclose(F);
 +
} /* End of 'LoadArray' function */
  
c = a - b;
+
/* Fill mas function */
//Результат вычитания второй функции из первой
+
// Заполнение массива координат точек с цветом
c.writeFile("outputAsubB.txt");
+
void graph::Fill( double(*f)(double) )
 
+
{
c = a*b;
+
// Выделение памяти под массив точек
//Результат умножения двух функций
+
mas = new vec[N];
c.writeFile("outputAmultiB.txt");
+
// Выделение памяти под массив цветов
 +
Color = new vec[N];
  
c = a / b;
+
// Заполнение массивов
//Результат деления первой функции на вторую
+
for (int i = 0; i < N; i++)
c.writeFile("outputAdivB.txt");
+
{
 +
mas[i] = vec(MinX + i * Step, f(MinX + i * Step));
 +
Color[i] = vec::Rnd();
 +
}
 +
} /* End of 'Fill' function */
  
//У первой функции изменили шаг на 0.5
+
/* Draw graph function */
a.changeDx(0.5);
+
// Рисование заполненного графика на экран
//Вывели её дискретные значения
+
void graph::Draw( void )
a.writeFile("outputChangeDx.txt");
+
{
 +
  // Задача размер точки
 +
glPointSize(1);
 +
// Рисование
 +
glBegin(GL_POINTS);
 +
for (int i = 0; i < N; i++)
 +
glVertex2d(mas[i].X, mas[i].Y);
 +
glEnd();
 +
} /* End of 'Draw' function */
  
//Функция, которая аппроксимирует её кусочно линейная.
+
/* Draw graph function */
//Для примера нашли значение аппроксимируещей функции в точке не совпадающей с дискретными значениями.
+
// Рисование не заполненного еще графика на экран
printf("Значение в точке 1.8 первой функции %.5lf\n", a.getX(1.8));
+
void graph::Draw( double(*f)(double) )
 
+
{
//Нужно чтобы окно консоли автоматически не закрылось
+
// Заполнение массива
system("pause");
+
graph::Fill(f);
return 0;
 
}
 
</syntaxhighlight>
 
</div>
 
  
 +
// Задача цвета и размера точки
 +
glColor3d(0, 0, 0);
 +
glPointSize(1);
 +
// Рисование
 +
glBegin(GL_POINTS);
 +
for (int i = 0; i < N; i++)
 +
glVertex2d(mas[i].X, mas[i].Y);
 +
glEnd();
 +
} /* End of 'Draw' function */
  
 +
/* Interpolation draw graph function */
 +
// Рисование интерполированного графика на экран
 +
void graph::Interpolation_Draw( double i_step )
 +
{
 +
// Коэффициент Катмулл-Рома
 +
double alpha = 1.0 / 6;
 +
 +
// Кубическая интерполяция кривыми Безье
 +
for (int i = 0; i < N - 1; i++)
 +
{
 +
// Создание 4 точек для интерполяции по ним
 +
vec P0 = mas[i], P1, P2, P3 = mas[i + 1];
 +
vec Color0 = mas[i], Color1, Color2, Color3 = mas[i + 1];
  
Скачать можно [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 здесь]
+
// Значения для первого и последнего отрезков
 
+
if (i == 0)
 
+
{
'''[[Сенников Иван]]'''
+
P1 = (mas[1] - mas[0]) * alpha + mas[0];
+
Color1 = (mas[1] - mas[0]) * alpha + mas[0];
'''Суть программы:''' Программы позволяет задать 2 функции с любыми областями определения и любыми множествами значений, интерполировать их на любом шаге, аппроксимировать, а так же сложить 2 существующие функции. Программа написана в классе работы с функциями.
+
}
 
+
else
'''Идея:''' Класс работы с функциями содержит такие функции как функция введения данных функции - ее создание, перегрузки оператора сложения, линейных интерполяции и аппроксимации, выделения и освобождения памяти. Линейная интерполяция написана с помощью теории аналитической геометрии на плоскости, а линейная аппроксимация с помощью метода наименьших квадратов.
+
{
 +
P1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
 +
Color1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
 +
}
 +
if (i == N - 2)
 +
{
 +
P2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
 +
Color2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
 +
}
 +
else
 +
{
 +
P2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
 +
Color2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
 +
}
  
'''Инструкция:''' Программа выполнена в виде меню на английском языке: пользователю будет предоставлена возможность выйти из программы, создать обе функции, а также поработать с ними в индивидуальном порядке и сложить две уже существующие функции. Комментарии к программе написаны также на английском языке.
+
glLineWidth(2);
 +
glBegin(GL_LINE_STRIP);
 +
for (double t = 0; t <= 1; t += i_step)
 +
{
 +
vec p, color;
  
Ссылка для скачиваний: [http://tm.spbstu.ru/Файл:Func.zip здесь].
+
// Вычисление точки интерполированного графика по 4 точкам
 +
p = P0 * (1 - t) * (1 - t) * (1 - t) + P1 * 3 * (1 - t) * (1 - t) * t + P2 * 3 * (1 - t) * t * t + P3 * t * t * t;
 +
color = Color0 * (1 - t) * (1 - t) * (1 - t) + Color1 * 3 * (1 - t) * (1 - t) * t + Color2 * 3 * (1 - t) * t * t + Color3 * t * t * t;
  
 +
// Рисование
 +
glColor3d(color.X / 10, 0, color.Y);
 +
glVertex2d(p.X, p.Y);
 +
}
 +
glEnd();
 +
}
 +
} /* End of 'Interpolation_Draw' function */
  
'''[[Степанянц Степан]]'''
+
/* Interpolation graph function */
+
// Интерполяция графика
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.Данныеберутся из файла.
+
graph graph::Interpolation( double i_step )
<div class="mw-collapsible-content">
+
{
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
graph G_New;
 +
// Коэффициент Катмулл-Рома
 +
double alpha = 1.0 / 6;
  
 +
// Заполнение параметров для нового графика
 +
G_New.MinX = MinX;
 +
G_New.MaxX = MaxX;
 +
G_New.Step = Step * i_step;
 +
G_New.N = (int)((G_New.MaxX - G_New.MinX) / G_New.Step);
 +
G_New.mas = new vec[G_New.N];
 +
 +
// Кубическая интерполяция кривыми Безье
 +
for (int i = 0; i < N - 1; i++)
 +
{
 +
// Создание 4 точек для интерполяции по ним
 +
vec P0 = mas[i], P1, P2, P3 = mas[i + 1];
 +
 +
// Значения для первого и последнего отрезков
 +
if (i == 0)
 +
P1 = (mas[1] - mas[0]) * alpha + mas[0];
 +
else
 +
P1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
 +
if (i == N - 2)
 +
P2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
 +
else
 +
P2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
 +
 +
for (double t = 0; t <= 1; t += i_step)
 +
{
 +
vec p;
 +
 +
// Вычисление точки интерполированного графика по 4 точкам
 +
G_New.mas[(int)((t + i) / i_step)] = P0 * (1 - t) * (1 - t) * (1 - t) + P1 * 3 * (1 - t) * (1 - t) * t + P2 * 3 * (1 - t) * t * t + P3 * t * t * t;
 +
}
 +
}
  
#include <iostream>
+
return G_New;
#include <vector>
+
} /* End of 'Interpolation' function */
#include <math.h>
+
 
#include <fstream>
+
/* Sum of 2 graphics function */
#include <stdio.h>
+
// Сложение двух графиков
#include <string>
+
graph graph::operator+( graph &G )
#include <time.h>
+
{
+
graph G_New, G1, G2;
using namespace std;
+
int i, j;
+
 
class func {
+
// Заполнение параметров графика суммы
    vector <double> vals;
+
G_New.MinX = (MinX >= G.MinX) ? MinX : G.MinX;
    double a, b, step, sz;
+
G_New.MaxX = (MaxX <= G.MaxX) ? MaxX : G.MaxX;
+
G_New.Step = Step * G.Step;
public:
+
G_New.N = (int)((G_New.MaxX - G_New.MinX) / G_New.Step);
    func (string fil) { //конструктор для ввода функции из файла
+
G_New.mas = new vec[G_New.N];
        ifstream f(fil.c_str());
+
 
        double a, b, step, y;
+
// Интерполяция слагаемых графиков, для приведение к общему шагу
        f >> a >> b >> step; //вводим основные значения из файла
+
G1 = Interpolation(G.Step);
        this->step = step;
+
G2 = G.Interpolation(Step);
        this->sz = (int)((b - a) / step + 1); //считаем размер
+
 
        this->a = a, this->b = b;
+
// Поиск общего начала и конца графиков
        for (int i = 0; i < this->sz; i++) {
+
for (i = 0; i < G1.N; i++)
            f >> y;
+
if (fabs(G1.mas[i].X - G_New.MinX) <= Threshold)
            this->vals.push_back(y); //считываем и записываем значения из файла
+
break;
        }
+
 
        f.close();
+
for (j = 0; j < G2.N; j++)
    }
+
if (fabs(G2.mas[j].X - G_New.MinX) <= Threshold)
    func () {} //еще один конструктор
+
break;
    func operator + (func a) { // эта и ближайшие четыре метода -- калькулятор функций
+
 
        func f = *new func(); //создаем новый экземпляр класса, ответ
+
// Заполнение графика суммы
        for (int i = 0; i < sz; i++) {
+
for (int k = 0; k < G_New.N; k++)
            f.vals.push_back(this->vals[i] + a.vals[i]); // складываем покоординатно
+
{
        }
+
G_New.mas[k].X = G_New.MinX + k * G_New.Step;
        f.step = a.step; // копируем все значения в ответ (возможно, это можно сделать гораздо проще и не писать 4*4 строк но почему-то ничего умнее я не придумал)
+
G_New.mas[k].Y = G1.mas[i + k].Y + G2.mas[j + k].Y;
        f.a = a.a;
+
}
        f.b = a.b;
+
 
        f.sz = a.sz;
+
return G_New;
        return f;
+
} /* End of 'Sum' function */
    }//Перегрузки операторов
+
 
    func operator - (func a) {
+
/* Save Array of points function */
        func f = *new func();                 
+
// Сохранение графика в файл по точкам
        for (int i = 0; i < a.sz; i++) {
+
void graph::SaveArray( void )
            f.vals.push_back(this->vals[i] - a.vals[i]);    //Вычитание
+
{
        }
+
// Создание указателя на тип FILE
        f.step = a.step;
+
FILE *F;
        f.a = a.a;
+
 
        f.b = a.b;
+
// Создание файла и открытие его в режиме записи
        f.sz = a.sz;
+
fopen_s(&F, "graph.txt", "wt");
        return f;
+
 
    }
+
/* Запись в файл данных */
    func operator * (func a) {
+
// Количество точек
        func f = *new func();
+
fprintf(F, "%d\n", N);
        for (int i = 0; i < a.sz; i++) {
+
// Шаг функции
            f.vals.push_back(this->vals[i] * a.vals[i]);   //умножение
+
fprintf(F, "%lf\n", Step);
        }
+
// Начальная координата по X
        f.step = a.step;
+
fprintf(F, "%lf\n", MinX);
        f.a = a.a;
+
// Конечная координата по X
        f.b = a.b;
+
fprintf(F, "%lf\n", MaxX);
        f.sz = a.sz;
+
 
        return f;
+
// Координаты всех точек
    }
+
for (int i = 0; i < N; ++i)
    func operator / (func a) {
+
  fprintf(F, "%lf %lf ", mas[i].X, mas[i].Y);
        func f = *new func();
+
 
        for (int i = 0; i < a.sz; i++) {
+
// Закрытие файла
            f.vals.push_back(this->vals[i] / a.vals[i]);   // Деление
+
fclose(F);
        }
+
} /* End of 'SaveArray' function */
        f.step = a.step;
+
 
        f.a = a.a;
+
/* Approximation of function function */
        f.b = a.b;
+
// Аппроксимация графика
        f.sz = a.sz;
+
void graph::Approximation( void )
        return f;
+
{
    }
+
double k, b, s1 = 0, s2 = 0, s3 = 0, s4 = 0;
+
 
    pair<double, double> approx() { //аппроксимация.
+
// Линейная аппроксимация
        double mid = 0;
+
for (int i = 0; i < N; i++)
        for (int i = 0; i < this->sz; i++) {
+
{
            mid += this->a + i * this->step;
+
if (fabs(mas[i].X) < MAX && fabs(mas[i].Y) < MAX)
        }
+
{
        mid /= this->sz;
+
s1 += mas[i].X * mas[i].Y;
        double d = 0;
+
s2 += mas[i].X;
        for (int i = 0; i < this->sz; i++) {
+
s3 += mas[i].X * mas[i].X;
            d += pow((this->a + i * this->step - mid), 2.);
+
s4 += mas[i].Y;
        }
+
}
        double a = 0;
+
}
        for (int i = 0; i < this->sz; i++) {
+
 
            a += (this->a + i * this->step - mid) * this->vals[i];
+
k = (N * s1 - s2 * s4) / (double(N) * s3 - s2 * s2);
        }
+
b = (s4 - k * s2) / double(N);
        a /= d;
+
 
        double midy = 0;
+
// Задача цвета и ширины линии
        for (int i = 0; i < this->sz; i++) {
+
glColor3d(1, 0.5, 0);
            midy += this->vals[i];
+
glLineWidth(1);
        }
+
// Рисование
        midy /= this->sz;
+
glBegin(GL_LINE_STRIP);
        double c = midy - a * mid;
+
glVertex2d(MinX, MinX * k + b);
        return {a, c}; //{x,y} возвращает пару (на самом деле не пару а просто какой-нибудь объект) с первым значением x и вторым y
+
glVertex2d(MaxX, MaxX * k + b);
    }
+
glEnd();
+
} /* End of 'Approximation' function */
    func inter(double step) {
+
 
        func f = *new func(); //ответ
+
/* End of 'GRAPH.CPP' file */
        double curr2, curr1;
+
</syntaxhighlight>
        int j = 0;
+
"'''GRAPH.H'''"
        f.a = this->a, f.b = this->b, f.step = step, f.sz = (int)((b - a) / step + 1);
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
        for (int i = 0; i < f.sz; i++) {
+
/* FILENAME: GRAPH.H
            curr2 = a + i * step;
+
* LAST UPDATE: 17.01.2016
            curr1 = a + j * this->step;
+
  */
            while (curr1 + this->step <= curr2) {
+
 
                j++, curr1 += this->step;
+
#ifndef _GRAPH_H_
            }
+
#define _GRAPH_H_
            if (curr1 == curr2) {
+
 
                f.vals.push_back(this->vals[j]);
+
#define _CRT_SECURE_NO_WARNINGS
                continue;
+
 
            }
+
#include <iostream>
            f.vals.push_back((this->vals[j + 1] - this->vals[j]) * (curr2 - curr1) / this->step + this->vals[j]);//я хз, тут видимо какая-то математика
+
#include <stdio.h>
        }
+
#include <stdlib.h>
        return f;
+
#include <math.h>
    }
+
#include <time.h>
    void write(string fil) { //запись. чтобы записать не в файл, а в консоль вывести, надо передать "-1"
+
#include <GL\glut.h>
        ofstream f(fil.c_str());
+
 
        if (fil != "-1") {
+
#define MAX 100
            f << this->a << ' ' << this->b << ' ' << this->step << '\n';
+
 
        }
+
using namespace std;
        else
+
 
            cout << this->a << ' ' << this->b << ' ' << this->step << '\n';
+
/* Useful constants */
        for (int i = 0; i < sz; i++) {
+
const double Threshold = 1e-10;
            if (fil != "-1")
+
const double Infinity = 1e+10;
                f << this->vals[i] << '\n';
+
 
            else
+
/* Vector representation type */
                cout << this->vals[i] << '\n';
+
class vec
        }
+
{
        f.close();
+
public:
   
+
double X, Y;
    }
+
 
};
+
/* Default constructor */
+
vec( void )
int main() {
+
{
    string fil;
+
}
    cout << "Input the file name with the function values\n";
+
 
    cin >> fil;
+
/* Class constructor */
    func f = *new func(fil);
+
vec( double A ) : X(A), Y(A)
    int a;
+
{
    char ch;
+
}
    double st;
+
 
    while (true) {
+
/* Class constructor */
        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";
+
vec( double A, double B ) : X(A), Y(B)
        cin >> a;
+
{
        if (a == 4) {
+
}
            cout << "input file name to write to\n";
+
 
            cin >> fil;
+
static double R0( void )
            f.write(fil);
+
{
        }
+
return rand() / (double)RAND_MAX;
        if (a == 3) {
+
} /* End of 'R0' function */
            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);
 
        }
 
        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);
 
        }
 
        if (a == 6)
 
            return 0;
 
    }
 
}
 
</syntaxhighlight>
 
</div>
 
  
'''[[Сюрис Александр]]'''
+
static vec Rnd( void )
Задаются две функции с разными шагами и начальными и конечными значениями.  Аппроксимирует одну функцию по шагу другой и складывает/умножает/вычитает/делит их
+
{
 +
return vec(R0(), R0());
 +
} /* End of 'Rnd' function */
  
Скачать можно  [http://mech.spbstu.ru/File:%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F(%D0%A1%D1%8E%D1%80%D0%B8%D1%81%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80).zip тут].
+
/* The functions of operations on vectors */
  
<div class="mw-collapsible-content">
+
/* Vector = vector function */
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
vec operator=( vec &B )
 +
{
 +
X = B.X;
 +
Y = B.Y;
  
#include <iostream>
+
return B;
#include <vector>
+
} /* end of 'operator+' function */
#include<math.h>
 
  
using namespace std;
+
/* Vector add vector function */
class f{
+
vec operator+( const vec &B ) const
    private:
+
{
    double st, en, d; //начало, конец, дельта
+
return vec(X + B.X, Y + B.Y);
    vector<double> v;//вектор, содержащий y
+
} /* end of 'operator+' function */
    public:
 
    f(double _st, double _en, double _d, vector<double> _v){
 
        st=_st;
 
        en=_en;
 
        d=_d;
 
        for(int i=0;i<_v.size();i++) //копируем массив, который вводим в консоль
 
            v.push_back(_v[i]);
 
        //return *this;
 
    }
 
    f(){};
 
    f aprox(double _st, double _en, double _d){ //метод интерполяции, поиск коэфф a и b для y=ax+b
 
        double sum_x=0, sum_y=0, sum_2x=0,sum_xy=0,a,b;
 
        for(int i=0; i<=(en-st)/d; i++)
 
            sum_x=sum_x+st+i*d;
 
        for(int i=0; i<=(en-st)/d; i++)
 
            sum_y=sum_y+v[i];
 
        for(int i=0; i<=(en-st)/d; i++)
 
            sum_2x=sum_2x+pow(st+i*d,2);
 
        for (int i=0; i<=(en-st)/d; i++)
 
            sum_xy=sum_xy+v[i]*(st+i*d);
 
        a=(((en-st)/d+1)*sum_xy-sum_x*sum_y)/(((en-st)/d+1)*sum_2x-sum_x*sum_x);
 
        b=(sum_y-a*sum_x)/(((en-st)/d+1));
 
  
        vector<double> v1;//вектор, содержащий проинтерполированную функцию
+
/* Vector sub vector function */
            for(int i=0; i<=(en-st)/d; i++)
+
vec operator-( const vec &B ) const
                v1.push_back(a*(st+i*d)+b);//добавление значений проинтерполированной ф-ции с шагом другой функции
+
{
        return f(_st,_en,_d,v1);
+
return vec(X - B.X, Y - B.Y);
 +
} /* end of 'operator-' function */
  
    }
+
vec operator-( void ) const
 +
{
 +
return vec(-X, -Y);
 +
} /* end of 'operator-' function */
  
    f operator +(f x){//оператор сложения
+
/* Vector mul number function */
        double _en,_st,_d;
+
vec operator*( const double N ) const
        _en=min(en,x.en); //поиск области пересечения
+
{
        _st=max(st,x.st);
+
return vec(X * N, Y * N);
        if (_en>_st){//проверяем, пересекаются ли функции
+
} /* end of 'operator*' function */
            vector<double> _v;
 
            f y;
 
            if(x.st<st){ //сравниваем начала двух отрезков, для того, чтобы выбрать, какую функцию апроксимировать
 
                vector<double> _v;
 
                y=x.aprox(_st, _en, d);
 
                for (int i=0; i<=(_en-_st)/d; i++)
 
                    _v.push_back(y.v[i]+v[i]); //вектор с суммой функций
 
                return f(_st,_en,d,_v);
 
            }
 
            else{
 
                vector<double> _v;
 
                y=this->aprox(_st, _en, x.d); //this-> функция, в которой мы работаем
 
              for (int i=0; i<=(_en-_st)/x.d; i++)
 
                    _v.push_back(y.v[i]+x.v[i]);
 
                return f(_st,_en,x.d,_v);
 
            }
 
        }
 
    }
 
  
    f prot(){ //поиск противоположной функции
+
/* Vector div number function */
        for (int i=0; i<=(en-st)/d; i++)
+
vec operator/( const double N ) const
            v[i]=(-1)*v[i];
+
{
        return *this;
+
return vec(X / N, Y / N);
    }
+
} /* end of 'operator/' function */
 +
 
 +
/* Vector dot vector function */
 +
double operator&( const vec &B ) const
 +
{
 +
return double(X * B.X + Y * B.Y);
 +
} /* end of 'operator&' function */
 +
 
 +
vec & operator+=( const vec &B )
 +
{
 +
X += B.X;
 +
Y += B.Y;
  
    f operator - (f x){ //разность функций
+
return *this;
        return(*this + x.prot());
+
} /* end of 'operator+=' function */
    }
 
  
f operator *(f x){//оператор умножения
+
vec & operator-=( const vec &B )
        double _en,_st,_d;
+
{
        _en=min(en,x.en); //поиск области пересечения
+
X -= B.X;
        _st=max(st,x.st);
+
Y -= B.Y;
        if (_en>_st){//проверяем, пересекаются ли функции
+
 
            vector<double> _v;
+
return *this;
            f y;
+
} /* end of 'operator-=' function */
            if(x.st<st){ //сравниваем начала двух отрезков, для того, чтобы выбрать, какую функцию апроксимировать
 
                vector<double> _v;
 
                y=x.aprox(_st, _en, d);
 
                for (int i=0; i<=(_en-_st)/d; i++)
 
                    _v.push_back(y.v[i]*v[i]); //вектор с суммой функций
 
                return f(_st,_en,d,_v);
 
            }
 
            else{
 
                vector<double> _v;
 
                y=this->aprox(_st, _en, x.d); //this-> функция, в которой мы работаем
 
              for (int i=0; i<=(_en-_st)/x.d; i++)
 
                    _v.push_back(y.v[i]*x.v[i]);
 
                return f(_st,_en,x.d,_v);
 
            }
 
        }
 
    }
 
  
f obr(){
+
vec & operator*=( const double N )
  for (int i=0; i<=(en-st)/d; i++)
+
{
            v[i]=1/v[i];
+
X *= N;
        return *this;
+
Y *= N;
}
 
  
f operator /(f x){
+
return *this;
return(*this*x.obr());
+
} /* end of 'operator*=' function */
}
 
  
    void vivod(){ //вывод
+
vec & operator/=( const double N )
    for(int i=0; i<v.size(); i++)
+
{
        cout<<v[i]<<" ";
+
X /= N;
 +
Y /= N;
  
    }
+
return *this;
};
+
} /* end of 'operator/=' function */
int main(){
 
    setlocale(LC_ALL, "Russian");
 
    double a,b,a1,b1,d,d1,t;
 
    int o;
 
    cout << "Введите начала и конец отрезка и дельту: ";
 
    cin>>a>>b>>d;
 
    int amount=(b-a)/d+1,amount2;
 
    vector<double>x;
 
    cout << "Введите " << amount << " значений функции на данном интервале:";
 
    for (int i=0; i<amount; i++)
 
    {
 
        cin>>t;
 
        x.push_back(t);
 
    }
 
  
    cout << "Проделаем ровно то же самое для 2 функции ";
+
double operator!( void ) const
    cout << "Введите начала и конец отрезка и дельту: ";
+
{
    cin >> a1 >> b1 >> d1;
+
return double(X * X + Y * Y);
 +
} /* end of 'operator!' function */
  
    amount2=(b1-a1)/d1+1;
+
/* Access vector components by index function */
    vector<double>y;
+
double operator[]( const int i ) const
    cout << "Введите " << amount2 << " значений функции на данном интервале:";
+
{
    for (int i=0; i<amount2; i++)
+
switch (i)
    {
+
{
        cin>>t;
+
case 0:
        y.push_back(t);
+
return double(X);
    }
+
case 1:
    f g(a,b,d,x);
+
return double(Y);
    f h(a1,b1,d1,y);
+
}
 +
} /* end of 'operator[]' function */
  
    cout<<"Выберете дейстивя с функциями: +, -, *, \ " << endl;
+
/* Normalizing vector function */
    cout<<"Введите число, соответсвующее порядковому номеру операции(1-4) - ";
+
vec & Normalize( void )
    cin>>o;
+
{
    if(o==1){              //по невыясненным причинам одновременно написанные слева идущие if -ы не работают,
+
double len = !*this;
        cout<<"Сумма:";    //но если заккоментить их и менять знак + в скобке на другие, то все работает
 
        (g+h).vivod();
 
  
    }
+
if (len != 1 && len != 0)
 +
*this /= sqrt(len);
 +
return *this;
 +
} /* end of 'Normalize' function */
 +
}; /* end of 'vec' class */
  
    if(o==2){
+
/* Graph class */
        cout<<"Разность:"
+
class graph
        (g-h).vivod();
+
{
 +
public:
 +
double MinX, MaxX, Step; // Начальная координата по X; Конечная координата по X; Шаг функции
 +
int N; // Количество точек
 +
vec *mas, *Color; // Массивы точек и цветов
  
    }
+
/* Default constructor */
 
+
graph( void )
    if(o==3){
+
{
        cout<<"Произведение:"
+
MinX = -10, MaxX = 10, Step = 0.1, N = 200;
        (g*h).vivod();
+
}
  
 +
/* Class constructor */
 +
graph( double _MinX, double _MaxX, double _Step ) : MinX(_MinX), MaxX(_MaxX), Step(_Step)
 +
{
 +
N = (int)((MaxX - MinX) / Step);
 +
// Выделение памяти
 +
mas = new vec[N];
 +
Color = new vec[N];
 +
}
  
    }
+
/* Load Array of points function */
 +
void LoadArray( char *FileName );
  
    if(o==3){
+
/* Fill mas function */
        cout<<"Отношение:"
+
void Fill( double(*f)(double) );
        (g/h).vivod();
 
    }
 
  
 +
/* Draw graph function */
 +
void Draw( double(*f)(double) );
  
}
+
/* Draw graph function */
 +
void Draw( void );
  
</syntaxhighlight>
+
/* Interpolation draw graph function */
</div>
+
void Interpolation_Draw( double i_step );
  
'''[[Тимошенко Валентина]]'''
+
/* Interpolation graph function */
 +
graph Interpolation( double i_step );
  
'''Краткое описание алгоритма''': в классе создаются две различные функции, а также функции для осуществления арифметических операций - сложения, вычитания, умножения и деления. Кроме того, созданы функции интерполяции и аппроксимации результата. Все результаты записываются в файлы, названия которых выводятся на экран в процессе работы программы.
+
/* Sum of 2 graphics function */
 +
graph operator+( graph &G );
  
'''Инструкция к программе''': при запуске программа предлагает ввести начало интервала, его конец и шаг для обеих функций. Далее пользователь выбирает одну из предложенных арифметических операций - сложение, вычитание, умножение или деление. После проведения вычислений программа предлагает пользователю интерполировать и аппроксимировать результат выбранной арифметической операции. Пользователь может давать команды на выполнение арифметических операций неограниченное число раз, программа завершает работу по команде пользователя.
+
/* Save Array of points function */
 +
void SaveArray( void );
  
 +
/* Approximation of function function */
 +
void Approximation( void );
 +
}; /* end of 'graph' class */
  
Скачать программу можно здесь: [http://tm.spbstu.ru/Файл:Program2.zip].
+
#endif /* _GRAPH_H_ */
  
<div class="mw-collapsible-content">
+
/* End of 'GRAPH.H' file */
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
</syntaxhighlight>
#include <iostream> ///программа, перегружающая операторы для работы с двумя функциями,
+
</div>
#include <fstream>  ///интерполирующая и аппроксимирующая результат арифметических операций над этими функциями
+
[http://tm.spbstu.ru/File:T05GRAPH.7z Скачать архив]
#include <math.h>
+
<br>
 
 
using namespace std;
 
 
 
class functions ///класс, хранящий значения введенных пользователем значений начала и конца исследуемого интервала, а также шага функции
 
{
 
private:
 
    double *massiv1, *massiv2, *massiv3; ///указатели на массивы, которые будут использованы в программе
 
    ///massiv1 - массив, хранящий изначальные значения функций, massiv2 - массив, хранящий значения одной из функций после интерполяции
 
    ///massiv3 - массив, хранящий значения суммы/разности/умножения/деления функций
 
    double quantity_before_interpolation, Begin, End, Step;
 
    ///quantity - количество элементов в массиве(переменная типа double), Begin и End - начало и конец рассматриваемого отрезка, Step - шаг функции
 
 
 
public:
 
 
 
    int amount_before_interpolation; ///amount - количество элементов в массиве (переменная типа int)
 
    functions (double Begin1, double End1, double Step1 ):Begin(Begin1), End(End1), Step(Step1) ///переменные, в которые закладываются значения, введенные пользоватедем
 
    {
 
        quantity_before_interpolation =((End-Begin)/Step) + 1; ///расчёт количества элементов в массиве
 
        amount_before_interpolation = static_cast < int >(quantity_before_interpolation); ///перевод значения количества элементов из типа double в тип int
 
    }
 
 
 
    void function1(double Begin, double End, double Step) ///задание первой функции
 
    {
 
        massiv1 = new double [amount_before_interpolation]; ///создание массива для хранения значений функций
 
        ofstream out ("Function1.txt"); ///запись в файл значений первой функции
 
        out << "The size of the range = " << amount_before_interpolation << '\n' << endl;; ///вывод на экран количества элементов данного массива
 
        for (int i = 0; i < amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 
        {
 
            massiv1[i] = 2*i*Step+Begin; ///формула вычисления
 
            out << "y(x=" << i << ")= " << massiv1[i] << endl; ///вывод на экран полученных значений
 
        }
 
        out.close(); ///завершение записи в файл
 
    }
 
 
 
    void function2(double Begin,double End,double Step) ///задание второй функции
 
    {
 
        massiv1 = new double [amount_before_interpolation]; ///создание массива для хранения значений функции
 
        ofstream out ("Function2.txt"); ///запись в файл значений второй функции
 
        out << "The size of the range = " << amount_before_interpolation << '\n' << endl;; ///вывод на экран количества элементов данного массива
 
        for (int i = 0; i < amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 
        {
 
            massiv1[i] = i*Step; ///формула вычисления
 
            out << "y(x=" << i << ")= " << massiv1[i] << endl; ///вывод на экран полученных значений
 
        }
 
        out.close(); ///завершение записи в файл
 
    }
 
 
 
    void interpolation (double Begin1, double End1, double Step2) ///интерполяция результата по новому шагу
 
    {
 
        ofstream out ("Interpolation.txt"); ///запись в файл интерполированных значений функции
 
        double quantity_after_interpolation =((End1-Begin1)/Step2) + 1; ///расчёт количества элементов в массиве
 
        int amount_after_interpolation = static_cast < int > (quantity_after_interpolation); ///перевод значения количества элементов из типа double в тип int
 
        out << "After interpolation the size of range = " << amount_after_interpolation << '\n' << endl;
 
 
 
        massiv3 = new double [amount_after_interpolation]; ///создание массива для хранения значений функции
 
        for (int i = 0; i < amount_after_interpolation; ++i) ///цикл, вычисляющий значения функции
 
        {
 
            double x = i*Step2 + Begin1; ///расчёт х-вой координаты
 
            double x0 = static_cast < int >((x - Begin1)/Step + Begin1); ///расчёт нулевой х-вой координаты
 
            ///перевод значения х0 из типа double в тип int
 
            ///расчёт х-вой координаты, считая от введенного значения начала интервала
 
            double x1 = x0 + Step; ///расчёт следующего значения х-вой координаты
 
            int i_0 = (x - Begin1)/Step; ///расчёт нулевого индекса
 
            int i0 = static_cast < int > (i_0); ///перевод нулевого индекса из типа double в тип int
 
            int i1 = i0 + 1; ///расчёт следующего индекса
 
            massiv3[i]=(((x - x0)*(massiv2[i1] - massiv2[i0]))/(x1-x0)) + massiv2[i0]; ///формула вычисления
 
            out <<  "y(x=" << i << ")= " << massiv2[i] << endl; ///вывод на экран полученных значений
 
        }
 
        out.close(); ///завершение записи в файл
 
    }
 
 
 
    void approximation(double Begin1, double End1, double Step2) ///функция, аппроксимирующая результат сложения/вычитания/умножения/деления функций
 
    {
 
        amount_before_interpolation=(End1-Begin1)/Step2+1;
 
        int SIZE = static_cast <int> (amount_before_interpolation); /// для удобства вводим переменную SIZE и закладываем в нее значение размера массива
 
 
 
        ///обнуление переменных
 
        double sumX = 0; ///переменная, хранящая значение суммы х-вых координат
 
        double sumY = 0; ///переменная, хранящая значение суммы у-вых координат
 
        double sumXY = 0; ///переменная, хранящая значение суммы произведений х-вой и у-вой координат
 
        double sumX2 = 0; ///переменная, хранящая значение суммы х-вых координат, взятых в квадрате
 
        double k=0; ///переменная, хранящая значения углового коэффициента касательной к графику данной функции
 
        double b=0; ///переменная, хранящая значение свободного коэффициента
 
        double d;
 
 
 
        ofstream out ("Approximation.txt"); ///запись в файл аппроксимированных значений
 
        for (int i = 0; i < SIZE; ++i) ///цикл для расчёта сумм, указанных выше
 
        {
 
            d=i*Step2+Begin1; ///расчёт х-вой координаты
 
 
 
            sumX = d + sumX; ///расчёт суммы х-вых координат
 
 
 
            sumY = massiv3[i] + sumY; ///расчёт суммы у-вых координат
 
 
 
            sumXY = d*massiv3[i] + sumXY; ///расчёт суммы произведений х-вой и у-вой координат
 
 
 
            sumX2 = d*d + sumX2; ///расчёт суммы х-вых координат, взятых в квадрате
 
        }
 
 
 
        k =(SIZE*sumXY - sumX*sumY)/(SIZE*sumX2- sumX*sumX); ///расчёт углового коэффициента
 
 
 
        b =(sumY - k*sumX)/SIZE; ///расчёт свободного коэффициента
 
 
 
        out << "The equation, which is got as a result of approximation" << endl; ///вывод уравнения на экран
 
 
 
        if (b > 0) ///вывод уравнения при положительном свободном коэффициенте
 
        {
 
            out << "y = " << k << "*x+" << b << endl;
 
        }
 
 
 
        else if (b < 0) ///вывод уравнения при отрицательном свободном коэффициенте
 
        {
 
            out << "y = " << k <<"*x" << b << endl;
 
        }
 
        out.close(); ///завершение записи в файл
 
    }
 
 
 
    ///перегрузка операторов
 
 
 
    functions operator+ (functions func3) ///сумма двух функций
 
    {
 
        massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
 
 
 
        ofstream out ("Results_of_sum.txt"); ///запись в файл значений после суммирования значений функций
 
        out << "sum of the functions" << '\n' << endl;
 
 
 
        for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 
        {
 
            massiv2[i] = massiv1[i] + func3.massiv1[i]; ///формула вычисления
 
            out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
 
        }
 
        out.close(); ///завершение записи в файл
 
 
 
        char d; ///переменная для команды интерполировать результат
 
        cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
 
        cin >> d;
 
 
 
        if (d=='+') ///если команда для интерполяции дана
 
        {
 
            double Step2; ///переменная, хранящая значение нового шага
 
            cout << '\n' << "Input the step for interpolation" << endl;
 
            cin >> Step2;
 
            interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
 
 
 
            char w; /// переменная для команды аппроксимировать результат
 
            cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
 
            cin >> w;
 
 
 
            if (w=='+') ///если команда на аппроксимацию дана
 
            {
 
                approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
 
            }
 
        }
 
    }
 
 
 
    functions operator- (functions func3) ///разность двух функций
 
    {
 
        massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
 
 
 
        ofstream out ("Results_of_difference.txt"); ///запись в файл значений второй функции
 
        out << "difference of the functions" << '\n' << endl;
 
 
 
        for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 
        {
 
            massiv2[i] = massiv1[i] - func3.massiv1[i]; ///формула вычисления
 
            out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
 
        }
 
        out.close(); ///завершение записи в файл
 
 
 
        char d; ///переменная для команды интерполировать результат
 
        cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
 
        cin >> d;
 
 
 
        if (d=='+') ///если команда для интерполяции дана
 
        {
 
            double Step2; ///переменная, хранящая значение нового шага
 
            cout << '\n' << "Input the step for interpolation" << endl;
 
            cin >> Step2;
 
            interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
 
 
 
            char w; /// переменная для команды аппроксимировать результат
 
            cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
 
            cin >> w;
 
 
 
            if (w=='+') ///если команда на аппроксимацию дана
 
            {
 
                approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
 
            }
 
        }
 
    }
 
 
 
    functions operator* (functions func3) ///произведение двух функций
 
    {
 
        massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
 
 
 
        ofstream out ("Results_of_multiplying.txt"); ///запись в файл значений второй функции
 
        out << "multiplying of the functions" << '\n' << endl;
 
 
 
        for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 
        {
 
            massiv2[i] = massiv1[i] * func3.massiv1[i]; ///формула вычисления
 
            out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
 
        }
 
        out.close(); ///завершение записи в файл
 
 
 
        char d; ///переменная для команды интерполировать результат
 
        cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
 
        cin >> d;
 
 
 
        if (d=='+') ///если команда для интерполяции дана
 
        {
 
            double Step2; ///переменная, хранящая значение нового шага
 
            cout << '\n' << "Input the step for interpolation" << endl;
 
            cin >> Step2;
 
            interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
 
 
 
            char w; /// переменная для команды аппроксимировать результат
 
            cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
 
            cin >> w;
 
 
 
            if (w=='+') ///если команда на аппроксимацию дана
 
            {
 
                approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
 
            }
 
        }
 
    }
 
 
 
    functions operator/ (functions func3) ///деление двух функций
 
    {
 
        massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
 
 
 
        ofstream out ("Results_of_dividing.txt"); ///запись в файл значений после деления значения первой функции на значения второй функции
 
        out << "dividing of the functions" << '\n' << endl;
 
 
 
      for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 
        {
 
            massiv2[i] = massiv1[i] / func3.massiv1[i]; ///формула вычисления
 
            out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
 
        }
 
        out.close(); ///завершение записи в файл
 
 
 
        char d; ///переменная для команды интерполировать результат
 
        cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
 
        cin >> d;
 
 
 
        if (d=='+') ///если команда для интерполяции дана
 
        {
 
            double Step2; ///переменная, хранящая значение нового шага
 
            cout << '\n' << "Input the step for interpolation" << endl;
 
            cin >> Step2;
 
            interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
 
 
 
            char w; /// переменная для команды аппроксимировать результат
 
            cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
 
            cin >> w;
 
 
 
            if (w=='+') ///если команда на аппроксимацию дана
 
            {
 
                approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
 
            }
 
        }
 
    }
 
};
 
 
 
int main()
 
{
 
    double Begin1, End1, Step1; ///переменные, вводимые пользователем
 
    cout << "Input the beginning of the interval" << endl; ///ввод начала отрезка
 
    cin >> Begin1;
 
    cout << '\n' << "Input the end of the interval" << endl; ///ввод конца отрезка
 
    cin >> End1;
 
    cout << '\n' << "Input the step of functions" << endl; ///ввод начального шага функций
 
    cin >> Step1;
 
 
 
    functions func1(Begin1, End1, Step1); ///вызов первой функции
 
    func1.function1(Begin1, End1, Step1);
 
    cout <<'\n' << "Meanings of the first function are saved in file called 'Function1.txt'" << endl;
 
 
 
    functions func2(Begin1, End1, Step1); ///вызов второй функции
 
    func2.function2(Begin1, End1, Step1);
 
    cout <<'\n' << "Meanings of the second function are saved in file called 'Function2.txt'" << endl;
 
 
 
    functions func3(Begin1,End1,Step1); ///вызов третьей функции
 
 
 
    char s; ///переменная, используется в цикле
 
    do
 
    {
 
        char c; ///переменная, хранящая выбор арифметической операции пользователем
 
        cout << '\n' << "Input your choice: + for sum,- for difference,* for multiplying,/ for dividing" << endl;
 
        cin >> c;
 
 
 
        if (c=='+') ///цикл, запускающий функцию расчёта суммы двух функций, их интерполяцию и аппроксимацию
 
        {
 
            func3=func1+func2; ///формула расчёта суммы
 
            cout << '\n' << "Results of sum are saved in file called 'Results_of_sum.txt'" << endl;
 
            cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
 
            cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
 
        }
 
        if (c=='-') ///цикл, запускающий функцию расчёта разности двух функций, их интерполяцию и аппроксимацию
 
        {
 
            func3=func1-func2; ///формула расчёта разности
 
            cout << '\n' << "Results of difference are saved in file called 'Results_of_difference.txt'" << endl;
 
            cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
 
            cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
 
        }
 
        if (c=='*') ///цикл, запускающий функцию расчёта произведения двух функций, их интерполяцию и аппроксимацию
 
        {
 
            func3=func1*func2; ///формула расчёта произведения
 
            cout << '\n' << "Results of multiplying are saved in file called 'Results_of_multiplying.txt'" << endl;
 
            cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
 
            cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
 
        }
 
        if (c=='/') ///цикл, запускающий функцию расчёта частного двух функций, их интерполяцию и аппроксимацию
 
        {
 
            func3=func1/func2; ///формула расчёта частного
 
            cout << '\n' << "Results of dividing are saved in file called 'Results_of_dividing.txt'" << endl;
 
            cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
 
            cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
 
        }
 
 
 
        cout << '\n' << "If you want program continue counting, input +, if not, input -" << endl;
 
        ///команда пользователя на продолжение работы цикла или же на его завершение
 
        cin >> s;
 
 
 
        if (s=='-') ///если дана команда на завершение работы цикла
 
        {
 
            cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
 
            cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
 
            return 0;
 
        }
 
    }
 
    while (s != '-'); ///работа цикла не завершается до тех пор, пока пользователь не даст соответствующую команду
 
 
 
}
 
 
 
</syntaxhighlight>
 
</div>
 
 
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
'''[[Уманский Александр]]'''
 
 
 
'''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется.
 
 
 
 
 
 
 
Скачать программу можно по [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:
 
    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>
 
Вам запрещено изменять защиту статьи. Edit Создать редактором

Обратите внимание, что все добавления и изменения текста статьи рассматриваются как выпущенные на условиях лицензии Public Domain (см. Department of Theoretical and Applied Mechanics:Авторские права). Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались любым желающим, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого.
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ, ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Отменить | Справка по редактированию  (в новом окне)