Информатика: Функции — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Изменения)
 
(не показано 25 промежуточных версий 17 участников)
Строка 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)                                        //базовая функция ( если задавать через шаг и начальный х
 
 
{
 
{
     return x;
+
private:
}
+
    double *mass1, *mass, *masss ;
 +
    double  AmountDouble, Begin, End, Step, Step2;
 +
public:
 +
     int  AmountInt;
 +
    func ( double _Begin, double _End, double _Step ):Begin(_Begin), End(_End), Step(_Step)
 +
    {
 +
        AmountDouble=((End-Begin)/Step)+1;///количество точек с данным шагом
 +
        AmountInt=static_cast<int>(AmountDouble);///так как количество это целое число, то округляем
  
struct ap                                                  //две одинаковые структуры это нехорошо,коненчо,но зато наглядно...
+
     }
{
 
     double k,b;
 
};
 
  
struct fun                                                  //один столбик в таблице функции
+
    void massiv1() ///создание первой функции х^3
{
+
    {
    double x,y;
+
        mass=new double[AmountInt];
};
+
        for (int l=0; l<AmountInt; l++)
 +
        {
 +
            mass[l] =pow((l*Step+Begin),3);
 +
        }
 +
        cout << "y=x^3 \n";
 +
    }
 +
    void massiv2() ///создание второй функции sin(x)
 +
    {
 +
        mass=new double[AmountInt];
 +
        for (int l=0; l<AmountInt; l++)
 +
        {
 +
            mass[l] =sin(l*Step+Begin);
 +
        }
 +
        cout << "y=sin(x) \n";
 +
    }
  
struct sf                                                  //структура нужная, для возражеия значений из функции "prepare" класса F
+
     void interpolation(double __Begin, double __End, double __Step)
{
+
     {
     int i1,i2,e1,e2;
 
     double glength, gfirstx, glastx;
 
};
 
  
double intr(double x1,double x2,double x,double y1,double y2)  // линенейная интерполяция
+
        double NewAmount=((__End-__Begin)/__Step) + 1;///количество точек для нового шага
{
+
        int NewAmountInt=static_cast<int>(NewAmount);
    return ( ((x-x1)/(x2-x1)) * (y2-y1) + y1 );
+
        for (int i=0; i<NewAmountInt; i++)///i-это точки функции с новыми шагами
}
+
        {
 
+
            mass1 = new double[NewAmountInt];
ap aproks(fun b [],int n)                                      //линейная аппроксимация
+
            double x = i*__Step+__Begin;///значения х в новых точках
{
+
            double x0=(static_cast<int>((x-__Begin)/Step)) * Step+__Begin;///значение х в точке интерполяции
    ap r;
+
            ///стоящей ДО новой точки
    double xy = 0,x = 0,y = 0,sqx = 0,xsq = 0;
+
            double x1=x0+Step;///точка интерполяции ПОСЛЕ новой точки, т.е к предыдущей прибавляем СТАРЫЙ шаг
    for (int i = 0; i < n; i++)                                 //вычисление коэффицентов
+
            int i0=(static_cast<int>((x-__Begin)/Step));///это нужно для массива, значение массива в i0 соответстует значению функции в x0
    {
+
            int i1=i0+1;
        xy  += b[i].x*b[i].y;
+
            mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
        x   += b[i].x;
+
            cout << "y("<<i<< ") = " << mass1[i] <<endl<<endl; ///вывод интерполяции на экран
        y   += b[i].y;
+
            std::ofstream fout("Interpol.txt",ios::app);///сохранение в файл
        sqx += b[i].x*b[i].x;
+
            fout<<i<<" "<<mass1[i]<<" \n";
         xsq += b[i].x;
+
            fout.close();
 +
         }
 +
        AmountInt=NewAmountInt;
 +
        delete[] mass;
 +
        mass=mass1;
 +
        cout<<"end of interpol";
 
     }
 
     }
    xsq *= xsq;
 
  
     r.k = (n*xy - x*y)/(n*sqx - xsq);                      //использование формул
+
     void approximation(double __Begin, double __End, double __Step)
    r.b = (y - r.k*x)/n;
 
    return r;
 
}
 
  
class F
 
{
 
private:
 
    int length;
 
    double firstx, step, lastx;
 
    fun *a;
 
public:
 
    F(){}
 
    F(int l,double f,double s)                              //конструктор, создающий фунцию по длине,первоиу элементу,шагу по х, y вычисляется по базовой функции
 
 
     {
 
     {
         if (l >= 0)
+
         double SumXMass=0;///это сумма умножений x на значение функции в этом x для всех значений
          a = new fun [l];
+
        double SumX=0;///сумма всех значений x
         firstx = f;
+
        double SumMass=0;///сумма всех значений функции в точках x
         length = l;
+
        double SumXX=0;///сумма всех квадратов значений x
        step = s;
+
        mass1 = new double[AmountInt];
        lastx = firstx+(length - 1)*step;
+
         double x;
 +
        for (int i=0; i<AmountInt; i++)
 +
         {
 +
            x=i*__Step+__Begin;///такие значения принимает x в точках по порядку i
 +
            SumXMass=SumXMass+x*mass[i];
 +
            SumX=SumX+x;
 +
            SumMass=SumMass+mass[i];
 +
            SumXX=SumXX+x*x;
  
 +
        }
 +
        double a=(SumXMass*AmountInt-SumX*SumMass)/(AmountInt*SumXX-SumX*SumX);
 +
        double b=(SumMass-a*SumX)/AmountInt;
 +
        if (b>0)
 +
            cout<<"approximation "<<a<<"*x+"<<b<<endl;
 +
        else if (b<0)
 +
            cout<<"approximation "<<a<<"*x"<<b<<endl;
  
         for (int i = 0;i < length; i ++)
+
         for (int i=0; i<AmountInt; i++)
 
         {
 
         {
             a[i].y = base(firstx + i*step);
+
             mass1[i] = a*(i*__Step+__Begin)+b;///такие значения принимает апроксимация
            a[i].x = firstx + i*step;
 
 
         }
 
         }
 +
        delete[] mass;
 +
        mass=mass1;
 +
        output();///вывод на экран
 +
        SaveFile("approximation.txt");///сохранение в файл
 +
        cout<<"end of appox";
  
 
     }
 
     }
  
     F (fun b[],int l)                                   //конструктор для создания фунции с уже известными областями определния и значений
+
     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];
+
        {
 +
             masss[i] = mass[i] + f.mass[i];
 +
        }
 +
        delete [] mass;
 +
        mass=masss;
 +
        output();///вывод на экран резултата
 +
        SaveFile("f3.txt");///сохранение в файл
 +
        cout<<"enter new step";
 +
        cin>>Step2;
 +
        cout<<"interpolation: ";
 +
        interpolation(Begin,End,Step2);///интерполяция
 +
        cout<<" approximation: ";
 +
        approximation(Begin,End,Step2);///аппроксимация
 +
        return newmass;
  
        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[] )                           //позволяет создать и заполнить переданным массивом поле объекта класса
+
     func operator-( func f)
 
     {
 
     {
         a = new fun [l];
+
         func newmass(Begin, End, Step);
         for (int i = 0; i < l; i++)
+
        masss=new double[AmountInt];
 +
         for (int i=0; i<AmountInt; i++)
 
         {
 
         {
             a[i].y = k*z[i].x + b;
+
             masss[i] = mass[i] - f.mass[i];
            a[i].x = z[i].x;
 
 
         }
 
         }
         length = l;
+
         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)
     double getelx(int i)                               //возращает значение из поля "х" iого элемента
 
 
     {
 
     {
         return a[i].x;
+
         func newmass(Begin, End, Step);
 +
        masss=new double[AmountInt];
 +
        for (int i=0; i<AmountInt; i++)
 +
        {
 +
            masss[i] = mass[i] / f.mass[i];
 +
        }
 +
        cout << " division: \n ";
 +
        delete [] mass;
 +
        mass = masss;
 +
        output();
 +
        SaveFile("f3.txt");
 +
        cout<<"enter new step";
 +
        cin>>Step2;
 +
        cout<<"interpolation: ";
 +
        interpolation(Begin,End,Step2);
 +
        cout<<" approximation: ";
 +
        approximation(Begin,End,Step2);
 +
        return newmass;
 
     }
 
     }
 
+
     func operator*( func f)
 
 
     double getely(int i)                               //возращает значение из поля "х" iого элемента
 
 
     {
 
     {
         return a[i].y;
+
         func newmass(Begin, End, Step);
    }
+
        masss=new double[AmountInt];
 
+
        for (int i=0; i<AmountInt; i++)
    int getlength()                                 //возращает размер области определения функции(в точках)
+
        {
    {
+
            masss[i] = mass[i] * f.mass[i];
         return length;
+
        }
 +
        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()///вывод функции на экран
 
     {
 
     {
      cout << "  x         y" << endl;
+
         for (int i=0; i<AmountInt; i++)
      for (int i = 0;i < length; i ++)
+
        {
          cout << "   " << a[i].x << "         " << a[i].y << endl;
+
            cout << "y("<<i<< ") = " << mass[i] <<endl;
      cout << endl;
+
 
 +
        }
 
     }
 
     }
  
  
     int pfind(double x)const                        //возращает либо номер элемента,идущщий перед элементом, большим,чем х; в случае нахождения равного, возращает число, противоположное номеру следующего элемента(иначе может вернуться нуль,а нуль знака не имееет)
+
     void SaveFile(char filename[])///сохранение функции в файл
 
     {
 
     {
         for (int i = 0; i < length-1; i++ )
+
        std::ofstream fout(filename);
 +
         for (int l=0; l<AmountInt; l++)
 
         {
 
         {
             if (((a[i].x < x) && (a[i + 1].x > x)))
+
             fout<<l<<" "<<mass[l]<<" \n";
                return (i + 1);
+
         }
            else
+
 
                // чтобы иметь возможность проанализировать полученное значение функции,мы должны понимать, было найденно равное или промежуточное значение. "флагом" равных значений является знак минус,но так у нуля нет знака,то приходиться все сдвигать на 1
+
         fout.close();
                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)
+
int main()
        {
+
{
            r.glastx = a[length - 1].x;
 
            r.e1 = length - 1;
 
            double k = x.pfind(r.glastx);
 
            if (k < 0)
 
                r.e2 = -k - 1;
 
            else
 
                r.e2 = (k - 1) - 1;
 
        }
 
        else
 
        {
 
            r.glastx = x.a[x.length - 1].x;
 
            double k = pfind(r.glastx);
 
            if (k < 0)
 
                r.e1 = -k - 1;
 
            else
 
                r.e1 = (k - 1) + 1;
 
            r.e2 = x.length - 1;
 
        }
 
        r.glength = length + x.length - r.i1 - (length - (r.e1 + 1)) - r.i2 - (x.length - (r.e2 + 1));
 
  
        return r;
+
    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;
  
     void ad (fun b[],int l)                                 //присвоить массиву объекта класса F значения массива b
+
     func f1(Begin1,End1,Step1);///создание первой функции
     {
+
     f1.massiv1();
        length = l;
+
    f1.output();
        a = new fun [l];
+
    cout<<"\n ";
        for (int i = 0; i < l;i++)
+
    f1.SaveFile("f1.txt");
            a[i] = b[i];
 
        firstx = a[0].x;
 
        lastx = a[length - 1].x;
 
    }
 
  
     fun *geta()                                         //получения указателя на начало массива в поле класса
+
     func f2(Begin1,End1,Step1);///создание второй функции
 +
    f2.massiv2();
 +
    f2.output();
 +
    cout<<"\n ";
 +
    f2.SaveFile("f2.txt");
 +
    cout<<"\n";
 +
 
 +
    func f3(Begin1,End1,Step1);
 +
 
 +
    cout<<" \n \n choose 1 - sum , 2 - subtract, 3 - division, 4 - multiply \n";///выбор операции
 +
    int z;
 +
    cin>>z;
 +
    switch (z)
 +
    {
 +
    case 1:
 +
    {
 +
        f3=f1+f2;///сумма функций
 +
        break;
 +
    }
 +
    case 2:
 +
    {
 +
        f3=f1-f2;
 +
        break;
 +
    }
 +
    case 3:
 +
    {
 +
        f3=f1/f2;
 +
        break;
 +
    }
 +
    case 4:
 
     {
 
     {
         return a;
+
         f3=f1*f2;
 +
        break;
 
     }
 
     }
  
     F operator +(F &x) const                              //сложение двух функций
+
     default :
 
     {
 
     {
         int i1, e1, i2, e2, kk = 0;
+
         cout<<"NOOOOO";
        double gfirstx, glastx, glength;
+
        break;
 
+
    }
        if (((x.lastx < firstx) && (x.firstx < firstx)) || ((lastx < x.firstx) && (firstx < x.firstx)))
+
    };
        {
+
    return 0;
            cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
+
}
            F fl(-1,0,0);
+
 
            return fl;
+
 
        }
+
</syntaxhighlight>
        sf r = prepare(x);
+
</div>
        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
+
Скачать можно  [http://tm.spbstu.ru/Файл:inter.zip тут].
                tmp.a[i].y = intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y) + a[i + r.i1].y;
 
        }
 
        for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
 
        {
 
            int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
 
            if (ii >= 0)
 
            {
 
                tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
 
                tmp.a[i - kk].y = intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y) + x.a[i - (r.e1 - r.i1 + 1) + r.i2].y;
 
            }
 
            else
 
            {
 
                kk++;
 
                glength --;
 
                tmp.length --;
 
            }
 
        }
 
  
        for (int i = 0; i < glength; i++)
 
            for (int j = 0; j < glength - 1; j++)
 
            if (tmp.a[j].x > tmp.a[j + 1].x)
 
            {
 
                fun t = tmp.a[j];
 
                tmp.a[j] = tmp.a[j + 1];
 
                tmp.a[j + 1] = t;
 
            }
 
  
        return tmp;
+
'''[[Белоусова Екатерина]]'''
}
 
  
    F operator *(F & x) const                                        //умножение двух функций
+
'''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем пользователь выбирает одну из арифметических операций, которую он хочет применить к этим функциям. Создается третья функция. После пользователь вводит второй шаг для интерполяции. Третья функция интерполируется по новому шагу, а затем аппроксимируется.
    {
 
        int i1, e1, i2, e2, kk = 0;
 
        double gfirstx, glastx, glength;
 
  
        if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
+
'''Краткое описание алгоритма''': в классе при помощи массива создаются две функции, с которыми потом работает программа. Эти функции перегружаются операторами арифметических операций, где затем полученная новая функция интерполируется и аппроксимируется.
        {
 
            cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
 
            F fl(-1,0,0);
 
            return fl;
 
        }
 
  
        sf r = prepare(x);
+
Скачать программу можно по ссылке  [http://tm.spbstu.ru/Файл:задача_2.zip].
        F tmp(r.glength,r.gfirstx,r.glastx);
 
  
        for (int i = 0; i <= (r.e1 - r.i1); i++)
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
        {
+
<div class="mw-collapsible-content">
            tmp.a[i].x = a[i + r.i1].x;
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
            int ii = x.pfind(tmp.a[i].x);
+
#include <iostream>
            if (ii < 0)
+
#include <locale.h>
                tmp.a[i].y = x.a[-ii - 1].y * a[i + r.i1].y;
+
#include <math.h>
            else
+
#include <fstream>
                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;
+
#include<iomanip>
        }
 
        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++)
+
using namespace std;
            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;
+
class functya ///создаем класс функции
    }
+
{
  
    F operator ^(F & x) const                                  //возведение функции слева от оператора в степень функции справа от оператора
+
private: ///объявляем тип переменных в привате
     {
+
     double *mass, *mass1, *mass2; ///*mass, *mass1, *mass2 -определение двумерного массива
        int i1, e1, i2, e2, kk = 0;
+
    double start, ending, step, step2, amountdouble; ///start-начало, ending-конец, step-шаг, amountdouble-количество точек (типа double)
        double gfirstx, glastx, glength;
 
  
        if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
+
public: ///объявляем тип переменных в паблике
        {
+
    int amount; ///amoun-количество точек (типа int)
            cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
+
 
            F fl(-1,0,0);
+
functya (double _start, double _ending, double _step):start(_start),ending(_ending),step(_step) ///создаем конструктор функции с объявлением переменных
            return fl;
+
{
        }
 
  
        sf r = prepare(x);
+
    amountdouble=((ending-start)/step)+1; ///подсчитываем количество точек с заданым шагом
        F tmp(r.glength,r.gfirstx,r.glastx);
+
    amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
  
        for (int i = 0; i <= (r.e1 - r.i1); i++)
+
}
        {
 
            tmp.a[i].x = a[i + r.i1].x;
 
            int ii = x.pfind(tmp.a[i].x);
 
            if (ii < 0)
 
                tmp.a[i].y = pow(x.a[-ii - 1].y, a[i + r.i1].y);
 
            else
 
                tmp.a[i].y = pow(intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y), a[i + r.i1].y);
 
        }
 
        for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
 
        {
 
            int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
 
            if (ii >= 0)
 
            {
 
                tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
 
                tmp.a[i - kk].y = pow(intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y), x.a[i - (r.e1 - r.i1 + 1) + r.i2].y);
 
            }
 
            else
 
            {
 
                kk++;
 
                glength --;
 
                tmp.length --;
 
            }
 
        }
 
  
        for (int i = 0; i < glength; i++)
+
void massiv1 () ///создаем функцию массива
            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;
+
    mass=new double[amount]; ///создаем двумерный массив
 +
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
 +
    {
 +
         mass[l]= pow((l*step+start),3); ///при помощи массива задаем функцию с которой будем работать
 
     }
 
     }
};
+
    cout<< "\n";
 +
}
  
int main()
+
void massiv2 () ///создаем функцию массива
 
{
 
{
  /*
 
    F f1(5,-2,1.5);
 
    F f2(30,-10,0.5);
 
    F f3, f4;
 
    f1.FOut();
 
    f2.FOut();
 
    f3 = f1 + f2;
 
    f3.FOut();
 
    f4 = f1 * f2;
 
    f4.FOut();
 
    cout << " ________" << endl;
 
*/
 
    char vc, s[255], ce;
 
    ifstream infile;
 
    int n;
 
    fun *a;
 
    F f5,f6,f7,f8,f9;
 
  
     while(true)
+
     mass=new double[amount]; ///создаем двумерный массив
 +
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
 
     {
 
     {
    start :
+
         mass[l]= pow((l*step+start),2); ///при помощи массива задаем функцию с которой будем работать
         system("cls");
+
    }
        cout << "1 - Vvesti 1uu func"            << endl;
+
    cout<< "\n";
         cout << "2 - Vvesti 2uu func"            << endl;
+
 
         cout << "3 - Sloshit'"                   << endl;
+
}
        cout << "4 - Umnozhit'"                 << endl;
+
 
        cout << "5 - Vozvesti v stepen'"        << endl;
+
void interpol (double __start, double __ending, double __step) ///создаем функцию интерполяция с определением переменных
         cout << "6 - Aproximirovat'"             << endl;
+
{
         cout << "7 - Zapics' v file func"       << endl;
+
 
        cout << "8 - Zapics' v file aprok fun"   << endl;
+
    double amount1=((__ending-__start)/__step)+1; ///определяем тип и подсчитываем новое количество точек с новым шагом
        cout << "0 - Vihod"                     << endl;
+
    int amounti=static_cast<int>(amount1); ///преобразуем количество из типа double к типу int
         cin  >> vc;
+
 
        switch (vc)
+
    for (int i=0; i<amounti; i++) ///создаем цикл от 0 до amounti-нового количества точек
        {
+
    {
            case '0':
+
 
                return 0 ;
+
        mass1=new double[amounti];
            case '1':
+
        double x = i*__step+__start; ///определяем тип и расчитываем координату Х
                {
+
         double x0=(static_cast<int>((x-__start)/step)) * step+__start;///определяем тип и расчитываем координату х
                system("cls");
+
                                                                      ///в интерполирующейся точке, которая стоит до новой точки
                strcpy(s,"");
+
        double x1=x0+step;///определяем тип и расчитываем координату х1 прибавляя к предыдущей точке шаг
                delete []a;
+
        int i0=(static_cast<int>((x-__start)/step));///определяем значение массива в i0 соответстующей значению функции в x0
                a = NULL;
+
        int i1=i0+1;
                cout << "Vvedite imya fila" << endl;
+
        mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
                cin >> s;
+
         cout << "Х="<<i<<setw(10)<< "У= " << mass1[i] <<endl<<endl; ///выводим интерполяцию на экран
                strcat(s, ".txt");
+
         ofstream fout("interpol.txt",ios::app);///сохраняем в файл
                infile.open(s);
+
         fout<< "Х="<<i<<setw(10)<< "У="<<mass1[i]<<" \n";
                infile >> n;
+
         fout.close();
                a = new fun [n];
+
 
                for(int i = 0; i < n; i ++)
+
    }
                    infile >> a[i].x >> a[i].y;
+
 
                f5.ad(a,n);
+
    amount=amounti;
                f5.FOut();
+
    delete []mass;
                infile.close();
+
    mass = mass1;
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
 
                cin >> ce;
+
}
                while (true)
+
 
                if (ce == 'b')
+
void aprocsimation(double __start, double __ending, double __step) ///создаем функцию апроксимация с определением переменных
                    goto start;
+
{
                }
+
 
            case '2':
+
    int N=amount; ///определяем тип и значение переменной N (равна количеству точек с заданным шагом)
                {
+
    double SumXY=0; ///определяем тип и значение переменной SumXY ( сумма (Х*У) )
                system("cls");
+
    double SumX=0; ///определяем тип и значение переменной SumX ( сумма Х )
                strcpy(s,"");
+
    double SumY=0; ///определяем тип и значение переменной SumУ ( сумма У )
                delete []a;
+
    double Sum_Xkv=0; ///определяем тип и значение переменной Sum_Xkv ( сумма (Х*Х) )
                a = NULL;
+
    double Xi; ///определяем тип переменной Xi
                cout << "Vvedite imya fila" << endl;
+
 
                cin >> s;
+
    mass1 = new double[N]; ///создаем двумерный массив
                strcat(s, ".txt");
+
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
                infile.open(s);
+
    {
                infile >> n;
+
 
                a = new fun[n];
+
        Xi=i*__step+__start; ///расчитываем Хi
                for(int i = 0; i < n; i ++)
+
        SumXY=SumXY+Xi*mass[i]; ///расчитываем SumXY
                    infile >> a[i].x >> a[i].y;
+
        SumX=SumX+Xi; ///расчитываем SumX
                f6.ad(a,n);
+
        SumY=SumY+mass[i]; ///расчитываем SumY
                f6.FOut();
+
        Sum_Xkv=Sum_Xkv+Xi*Xi; ///расчитываем Sum_Xkv
                infile.close();
+
 
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
    }
                cin >> ce;
+
 
                while (true)
+
    double a=(SumXY*N-SumX*SumY)/(N*Sum_Xkv-SumX*SumX); ///определяем тип и расчитываем коэффициент перед Х в уравнении аХ+b
                if (ce == 'b')
+
    double b=(SumY-a*SumX)/N; ///определяем тип и расчитываем свободный член в уравнении аХ+b
                    goto start;
+
 
                }
+
    if (b>0) ///если b положительное то
            case '3':
+
    cout<<"Апроксимация: "<<a<<"*x+"<<b<<endl; ///выводим на экран: Апроксимация: а*Х+b
                system("cls");
+
 
                f5.FOut();
+
    else if (b<0) ///если b отрицательно то
                f6.FOut();
+
    cout<<"Апроксимация: "<<a<<"*x"<<b<<endl; ///выводим на экран: Апроксимация: а*Х b
                f7 = f5 + f6;
+
 
                f7.FOut();
+
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
    {
                cin >> ce;
+
        mass1[i] = a*(i*__step+__start)+b; ///при помощи массива создаем функцию подсчета точек при апроксимации
                while (true)
+
    }
                if (ce == 'b')
+
 
                    goto start;
+
    delete[] mass;
            case '4':
+
    mass=mass1;
                system("cls");
+
    vivod();///вывод на экран
                f5.FOut();
+
    zapis("aprocsimation.txt");///сохраненяем в файл
                f6.FOut();
+
 
                f7 = f5 * f6;
+
}
                f7.FOut();
+
 
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
functya operator+ ( functya F) ///перегрузка оператора +
                cin >> ce;
+
{
                while (true)
+
 
                if (ce == 'b')
+
    functya tmp(start,ending,step);
                    goto start;
+
 
            case '5':
+
    mass2=new double[amount];///создаем двумерный массив
                system("cls");
+
    for (int i=0; i<amount; i++)
                f5.FOut();
+
    {
                f6.FOut();
+
        mass2[i]=mass[i] + F.mass[i];///находим сумму двух функций
                f7 = f5 ^ f6;
+
    }
                f7 = f5 ^ f6;
+
    delete [] mass;
                f7.FOut();
+
    mass=mass2;
                cout << "Nazhmite \"b\" chotibi viti" << endl;
+
    vivod();///выводим на экран результат
                cin >> ce;
+
    zapis("f3.txt");///сохраненяем в файл
                while (true)
+
    cout<<"Введите шаг для интерполяции";
                if (ce == 'b')
+
    cin>>step2;
                    goto start;
+
    cout<<"Интерполяция: "<<"\n";
            case '6':
+
    interpol(start,ending,step2);///вызов функции интерполяции
            {
+
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
                system("cls");
+
    return tmp;
                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;
+
functya operator-( functya F)///перегрузка оператора -
                cin >> ce;
+
{
                while (true)
+
 
                if (ce == 'b')
+
    functya tmp(start,ending,step);
                    goto start;
+
 
            }
+
    mass2=new double[amount];///создаем двумерный массив
            case '7':
+
    for (int i=0; i<amount; i++)
            {
+
    {
                system("cls");
+
        mass2[i]=mass[i] - F.mass[i];///находим разность двух функций
                strcpy(s,"");
+
    }
                cout << "Vvedite imya fila" << endl;
+
 
                cin >> s;
+
    delete [] mass;
                strcat(s, ".txt");
+
    mass=mass2;
                ofstream outfile(s);
+
    vivod();///выводим на экран результат
                outfile << "x          y" << endl;
+
    zapis("f3.txt");///сохраненяем в файл
                for (int i = 0; i < f7.getlength(); i ++)
+
    cout<<"Введите шаг для интерполяции";
                    outfile << f7.getelx(i) << "          " << f7.getely(i) << endl;
+
    cin>>step2;
 +
    cout<<"Интерполяция: "<<"\n";
 +
    interpol(start,ending,step2);///вызов функции интерполяции
 +
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 +
    return tmp;
  
                cout << "done" << endl;
 
                cout << "Nazhmite \"b\" chotibi viti" << endl;
 
                cin >> ce;
 
                while (true)
 
                if (ce == 'b')
 
                    goto start;
 
            }
 
            case '8':
 
                system("cls");
 
                strcpy(s,"");
 
                cout << "Vvedite imya fila" << endl;
 
                cin >> s;
 
                strcat(s, ".txt");
 
                ofstream outfile(s);
 
                outfile << "x          y" << endl;
 
                for (int i = 0; i < f8.getlength(); i ++)
 
                    outfile << f8.getelx(i) << "          " << f8.getely(i) << endl;
 
                cout << "done" << endl;
 
                cout << "Nazhmite \"b\" chotibi viti" << endl;
 
                cin >> ce;
 
                while (true)
 
                if (ce == 'b')
 
                    goto start;
 
        }
 
    }
 
    return 0;
 
 
}
 
}
</syntaxhighlight>
 
</div>
 
  
 +
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;
  
'''Инструкция к программе''': Введите поочередно первый и последний элементы функций, а также их шаги. После этого введите число, соответствующее желаемому действию (соответствие указано в меню программы).
+
}
  
Посмотреть программу можно [http://tm.spbstu.ru/Файл:main.zip здесь]
+
functya operator/( functya F)///перегрузка оператора /
 +
{
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    functya tmp(start,ending,step);
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
  
#include <iostream>
+
    mass2=new double[amount];///создаем двумерный массив
#include <fstream>
+
    for (int i=0; i<amount; i++)
#include <cstring>
+
    {
#include <stdlib.h>
+
        mass2[i]=mass[i] / F.mass[i];///находим частное двух функций
 +
    }
  
using namespace std;
+
    delete [] mass;
 +
    mass=mass2;
 +
    vivod();///выводим на экран результат
 +
    zapis("f3.txt");///сохраненяем в файл
 +
    cout<<"Введите шаг для интерполяции ";
 +
    cin>>step2;
 +
    cout<<"Интерполяция: "<<"\n";
 +
    interpol(start,ending,step2);///интерполяция
 +
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 +
    return tmp;
  
ofstream outfile;
+
}
  
struct approx                                              //структура, необходимая для функции линейной интерполяции
+
void vivod ()///создаем функцию вывода на экран
 
{
 
{
    double koefficientA, koefficientB;
 
};
 
  
struct dot                                                  //структура, содержащая в себе значения координат каждой точки
+
    for (int l=0; l<amount; l++)
{                                                           //по обеим осям
+
    {
    double x, y;
+
        cout<<"Х"<<l<<setw(10)<< "Y= " << mass[l] <<"\n";
};
+
    }
  
struct polyana                                              //структура, содержащая номера первого и последнего элемента каждой
+
}
{                                                          //функции и количество элементов каждой из них
 
    int a1, a2, b1, b2, k1, k2;
 
};
 
  
struct trees                                                //структура, содержащая номер элемента и логическое значение,
+
void zapis (char Zapis[])///созданем функцию записи в файл
{                                                          // отвечающее за нужность или не нужность интерполяции
 
    bool pol;                                              //при равенстве или неравенстве энных элементов двух функций
 
    int n;
 
};
 
                                                            //непосредственно функция линейной интерполяции
 
double pentagon (double x1, double x, double x2, double y1, double y2)
 
 
{
 
{
     return (((x - x1)/(x2- x1))*(y2 - y1) + y1);
+
 
 +
     ofstream fout(Zapis);
 +
    for (int l=0; l<amount; l++)
 +
    {
 +
        fout<<"X="<<l<<setw(10)<<"Y="<<mass[l]<<" \n";
 +
    }
 +
 
 +
    fout.close();
 +
 
 
}
 
}
  
class stars                                                //класс, позволяющий сохранять дискретные значения функции на
+
};
{                                                          //определенном интервале с определенным шагом
 
    private:
 
  
        double a;                  //первое значение функции
+
int main()
        double b;                  //последнее значение функции
+
{
        double step;                //шаг
 
        int length;                //длина
 
        int k;                      //счетчик количества элементов
 
  
     public:
+
     setlocale(LC_ALL,"RUS");
  
        dot *massiv;
+
    double start1, ending1, step1, step2;
        stars (int _k)                                      //конструктор для создания объекта класса - структуры
+
    int number;
        {                                                  //с двумя полями по количеству элементов
+
    cout<< "Введите начало отрезка ";
            massiv = new dot [_k];
+
    cin>> start1;
            k = _k;
+
    cout<< "Введите конец отрезка ";
        }
+
    cin>> ending1;
        stars () {};                                       //конструктор
+
    cout<<"Введите шаг для функций ";
        stars (double _a, double _b, double _step)          //конструктор для создания объекта класса через начальный
+
    cin>> step1;
                                                            //и коненый элементы с определенным шагом
 
        {
 
            a = _a;
 
            b = _b;
 
            step = _step;
 
  
            length = _b - _a + 1;
+
    functya F1(start1,ending1,step1);///создаем первую функцию
            k = 0;
+
    F1.massiv1();
 +
    F1.vivod();///выводим координаты первой функции на экран
 +
    F1.zapis("F1.txt");///записываем координаты первой функции в файл
  
            for (int i = _a ; i <= _b ; i += step)          //подсчет количества элементов функции
+
    cout<<"\n \n";
            {
 
                k++;
 
            }
 
  
            massiv = new dot [k];                           //задание функции
+
    functya F2(start1,ending1,step1);///создаем вторую функцию
            for (int i = 0 ; i < k ; i++)
+
    F2.massiv2();
              {
+
    F2.vivod();///выводим координаты второй функции на экран
                    massiv[i].x = _a + _step * i;
+
    F2.zapis("F2.txt");///записываем координаты второй функции в файл
                    massiv[i].y = i * 5;
 
              }
 
        }
 
  
        void outinfile ()                                  //вывод в файл значений функции
+
    cout<<"\n \n";
        {
+
 
            outfile.open ("meow", ios :: app);
+
    functya F3(start1, ending1, step1);
  
            outfile << "x" << "          " << "y" << endl;
+
    cout<<"Выберите, что вы хотите сделать с функциями: 1-найти сумму, 2-найти разность, 3-найти произведение, 4-найти частное ";
            for (int i = 0 ; i < k ; i++)
+
    cin>>number;
                {
+
    cout<<"\n \n";
                    outfile << massiv[i].x << "       " << massiv[i].y << endl;
 
                }
 
            outfile << endl;
 
            outfile.close();
 
        }
 
  
        void out ()                                         //вывод на экран значений функции
+
    if(number==1)
        {
+
    {
            cout << "x" << "          " << "y" << endl;
+
        F3=F1+F2;
            for (int i = 0 ; i < k ; i++)
+
    }
                {
 
                    cout << massiv[i].x << "        " << massiv[i].y << endl;
 
                }
 
            cout << endl;
 
        }
 
  
        polyana prepare (stars &h)                          //подготовка совместной области определения для двух функций -
+
    else if (number==2)
        {                                                  //той части значений множества Х, на которой будут
+
    {
            trees del;                                      //производиться вычисления
+
        F3=F1-F2;
            polyana tmp;
+
    }
            if (massiv[0].x > h.massiv[0].x)                //поиск начала совместной области определения
 
            {
 
                del = h.love(massiv[0].x);
 
                tmp.a2 = del.n + 1;
 
                tmp.a1 = 0;
 
            }
 
            else
 
                if (massiv[0].x < h.massiv[0].x)
 
                {
 
                    del = love(h.massiv[0].x);
 
                    tmp.a2 = 0;
 
                    tmp.a1 = del.n + 1;
 
                }
 
                else
 
                    if (massiv[0].x == h.massiv[0].x)
 
                    {
 
                        tmp.a1 = 0;
 
                        tmp.a2 = 0;
 
                    };
 
  
            if (massiv[k-1].x > h.massiv[k-1].x)            //поиск конца совместной области определения
+
    else if (number==3)
            {
+
    {
                del = h.love(massiv[k-1].x);
+
        F3=F1*(F2);
                tmp.b2 = k-1;
+
    }
                tmp.b1 = del.n;
 
            }
 
            else
 
                if (massiv[k-1].x < h.massiv[k-1].x)
 
                {
 
                    del = h.love(massiv[k-1].x);
 
                    tmp.b2 = del.n;
 
                    tmp.b1 = k-1;
 
                }
 
                else
 
                    if (massiv[k-1].x == h.massiv[k-1].x)
 
                    {
 
                        tmp.b2 = k-1;
 
                        tmp.b1 = k-1;
 
                    };
 
  
            tmp.k1 = 0;
+
    else if (number==4)
            for (int i = tmp.a1 ; i <= tmp.b1 ; i ++)       //подсчет количества элементов первой функции
+
    {
            {
+
        F3=F1/F2;
                tmp.k1++;
+
    }
            }
 
            tmp.k2 = 0;
 
            for (int i = tmp.a2 ; i <= tmp.b2 ; i ++)      //подсчет количества элементов второй функции
 
            {
 
                tmp.k2++;
 
            }
 
            return tmp;                                     //возвращает первые и последние значения обеих функций и
 
        }                                                   //их количества элементов
 
  
     //ПЕРЕГРУЗКА ОПЕРАТОРОВ
+
     else
 +
    {
 +
        cout<<"Ошибка ";
 +
    }
  
     stars operator+ (stars & v)                            //сложение
+
     return 0;
    {
 
        polyana tmp = prepare(v);
 
        int general = tmp.k1 + tmp.k2;                      //общее количество элементов обеих функций
 
        stars F3(general);                                  //создание объекта класса только по количеству элементов
 
        for (int i = 0 ; i < tmp.k1 ; i++)                  //заполнение первой части окончательного результата
 
        {
 
            F3.massiv[i].x = massiv[i+tmp.a1].x;
 
            trees tiger = v.love(massiv[i+tmp.a1].x);
 
            if (tiger.pol == true)                          //если значения по У в одной точке не совпадают, то интерполировать
 
            {
 
                F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
 
                                          F3.massiv[i].x,
 
                                          v.massiv[tiger.n + 1].x,
 
                                          v.massiv[tiger.n].y,
 
                                          v.massiv[tiger.n + 1].y )
 
                                          + massiv[i+tmp.a1].y;
 
            }
 
            else                                            //иначе, просто сложить значения
 
            {
 
                F3.massiv[i].y = v.massiv[tiger.n].y + massiv[i+tmp.a1].y;
 
            }
 
  
        }
+
}
        {
+
</syntaxhighlight>
          for (int i = tmp.k1  ; i < (general) ; i++)      //заполнение второй части окончательного результата
+
</div>
        {
+
 
            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)
+
'''Инструкция к программе''':сначала в папке с программой создаются два файла input1 и input2, в которых на первой строчке число точек в функции, а потом в два столбика значения х и у (функции должны быть с одинаковым шагом). Пользователь поочередно выбирает действия: 1 - нужно будет написать имя файла, откуда считывать значения для первой функции (х и у), 2 - для второй функции, 3 - сложение функций, пишем название файла, куда будут записываться значения, 4 - разность, 5 - умножение, 6 - интерполяция функции с шагом 0,5 , получившейся в результате сложения двух начальных,(можно сделать интерполяцию функций, которые получились в результате разности или умножения, но нужно будет в коде в case 6: newf3.Inter(0.5).output() поменять индекс функции и новый шаг), 7 - аппроксимация функции, получившейся в результате сложения двух начальных,(можно сделать аппроксимацию функций, которые получились в результате разности или умножения, но нужно будет в коде в case 7: newf3.Approxy().output() поменять индекс функции), 8 - выход.
            {
+
 
                F3.massiv[i].y = pentagon  (v.massiv[tiger.n].x,
+
'''Краткое описание алгоритма''':  функции хранятся в программе как массив точек, заданных с определённым шагом по X на заданном отрезке. Вводить значения функции в программу можно считывая координаты точек из файла. Далее с любыми функциями можно производить следующие действия: сложение, вычитание, умножение, интерполяция и аппроксимация. При этом результат каждого из этих действий - новая функция. Результаты выводятся в файл.
                                            F3.massiv[i].x,
+
Скачать программу можно по ссылке [http://tm.spbstu.ru/Файл:1.zip].
                                            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;
+
'''Описание программы''': программа, с помощью которой можно складывать, умножать, вычитать, делить 2-е функции, аппроксимировать,интерполировать.
            }
+
 
            else
+
'''Суть программы:''' Программа позволяет задать 2 функции с любыми областями определения и любыми множествами значений, интерполировать их на любом шаге, аппроксимировать, а так же сложить 2 существующие функции. Программа написана в классе работы с функциями.
                F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
+
 
        }
+
'''Инструкция к программе''':
 +
1. Пользователь вводит параметры первой функции
 +
2. Пользователь вводит параметры второй функции
 +
3. Происходит интерполяция первой функции по второй
 +
4. Пользователь выбирает арифметическую операцию
 +
5. При желании пользователь может выполнить аппроксимацию полученного результата
 +
 
 +
Скачать можно [[http://mech.spbstu.ru/File:Gilmanov_Func.rar здесь]]
 +
 
 +
'''[[Демченко Артём]]'''
 +
 
 +
'''Описание программы''': В программе создается две функции, которые мы можем просуммировать, интерполировать каждую из них и аппроксимировать каждую из них. После каждой операции ( кроме аппроксимации ) значения записываются в файл.
 +
 
 +
'''Инструкции''': Запустите программу и выбором одного из трех параметров в меню выберете желаемую операцию. Далее следуйте указаниям из меню.  
  
        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--;
 
                }
 
            }
 
        }
 
  
 +
Скачать можно  [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);
+
Посмотреть программу можно [http://tm.spbstu.ru/Файл:main.zip здесь]
        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;
 
            }
 
  
        }
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
        {
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
            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++)
+
#include <iostream>
        {
+
#include <fstream>
            for (int j = 0; j < (general - 1); j ++)
+
#include <cstring>
            {
+
#include <stdlib.h>
                dot temp;
+
 
                if (F3.massiv[j].x > F3.massiv[j+1].x)
+
using namespace std;
                {
 
                    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++)
+
ofstream outfile;
        {
 
  
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
+
struct approx                                              //структура, необходимая для функции линейной интерполяции
        }
+
{
 +
    double koefficientA, koefficientB;
 +
};
  
 +
struct dot                                                  //структура, содержащая в себе значения координат каждой точки
 +
{                                                          //по обеим осям
 +
    double x, y;
 +
};
  
        stars normalny(general);
+
struct polyana                                              //структура, содержащая номера первого и последнего элемента каждой
        for (int i = 0; i < (general); i++)
+
{                                                           //функции и количество элементов каждой из них
        {
+
    int a1, a2, b1, b2, k1, k2;
            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)                            //вычитание
+
struct trees                                                //структура, содержащая номер элемента и логическое значение,
    {
+
{                                                           // отвечающее за нужность или не нужность интерполяции
        polyana tmp = prepare(v);
+
    bool pol;                                               //при равенстве или неравенстве энных элементов двух функций
        int general = tmp.k1 + tmp.k2;
+
    int n;
        stars F3(tmp.k1 + tmp.k2);
+
};
        for (int i = 0 ; i < tmp.k1 ; i++)
+
                                                            //непосредственно функция линейной интерполяции
        {
+
double pentagon (double x1, double x, double x2, double y1, double y2)
            F3.massiv[i].x = massiv[i+tmp.a1].x;
+
{
            trees tiger = v.love(massiv[i+tmp.a1].x);
+
    return (((x - x1)/(x2- x1))*(y2 - y1) + y1);
            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;
 
            }
 
  
 +
class stars                                                //класс, позволяющий сохранять дискретные значения функции на
 +
{                                                          //определенном интервале с определенным шагом
 +
    private:
 +
 +
        double a;                  //первое значение функции
 +
        double b;                  //последнее значение функции
 +
        double step;                //шаг
 +
        int length;                //длина
 +
        int k;                      //счетчик количества элементов
 +
 +
    public:
 +
 +
        dot *massiv;
 +
        stars (int _k)                                      //конструктор для создания объекта класса - структуры
 +
        {                                                  //с двумя полями по количеству элементов
 +
            massiv = new dot [_k];
 +
            k = _k;
 
         }
 
         }
 +
        stars () {};                                        //конструктор
 +
        stars (double _a, double _b, double _step)          //конструктор для создания объекта класса через начальный
 +
                                                            //и коненый элементы с определенным шагом
 
         {
 
         {
             for (int i = tmp.k1 ; i < (general) ; i++)
+
             a = _a;
        {
+
            b = _b;
             F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
+
            step = _step;
             trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
+
 
             if (tiger.pol == true)
+
             length = _b - _a + 1;
 +
             k = 0;
 +
 
 +
             for (int i = _a ; i <= _b ; i += step)         //подсчет количества элементов функции
 
             {
 
             {
                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
+
                 k++;
                                            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;
+
             massiv = new dot [k];                          //задание функции
 +
            for (int i = 0 ; i < k ; i++)
 +
              {
 +
                    massiv[i].x = _a + _step * i;
 +
                    massiv[i].y = i * 5;
 +
              }
 
         }
 
         }
  
         for (int i= 0; i < (general); i++)
+
         void outinfile ()                                   //вывод в файл значений функции
 
         {
 
         {
             for (int j = 0; j < (general - 1); j ++)
+
            outfile.open ("meow", ios :: app);
            {
+
 
                dot temp;
+
            outfile << "x" << "          " << "y" << endl;
                if (F3.massiv[j].x > F3.massiv[j+1].x)
+
             for (int i = 0 ; i < k ; i++)
 
                 {
 
                 {
                     temp = F3.massiv[j];
+
                     outfile << massiv[i].x << "        " << massiv[i].y << endl;
                    F3.massiv[j] = F3.massiv[j+1];
 
                    F3.massiv[j+1] = temp;
 
 
                 }
 
                 }
                else
+
            outfile << endl;
                if (F3.massiv[j].x == F3.massiv[j+1].x)
+
            outfile.close();
 +
        }
 +
 
 +
        void out ()                                        //вывод на экран значений функции
 +
        {
 +
            cout << "x" << "          " << "y" << endl;
 +
            for (int i = 0 ; i < k ; i++)
 
                 {
 
                 {
                     int l = j;
+
                     cout << massiv[i].x << "        " << massiv[i].y << endl;
                    while (l < general)
 
                    {
 
                        F3.massiv[j].x = F3.massiv[j+1].x;
 
                        l++;
 
                    }
 
                    general--;
 
 
                 }
 
                 }
             }
+
             cout << endl;
 
         }
 
         }
  
        for (int i = 0 ; i < general ; i++)
+
        polyana prepare (stars &h)                         //подготовка совместной области определения для двух функций -
        {
+
         {                                                   //той части значений множества Х, на которой будут
 
+
             trees del;                                     //производиться вычисления
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
+
            polyana tmp;
        }
+
            if (massiv[0].x > h.massiv[0].x)               //поиск начала совместной области определения
 
 
 
 
        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,
+
                 del = h.love(massiv[0].x);
                                          v.massiv[tiger.n + 1].x,  v.massiv[tiger.n].y,
+
                tmp.a2 = del.n + 1;
                                          v.massiv[tiger.n + 1].y )/ (massiv[i+tmp.a1].y);
+
                tmp.a1 = 0;
 
             }
 
             }
 
             else
 
             else
            {
+
                 if (massiv[0].x < h.massiv[0].x)
                 F3.massiv[i].y = (v.massiv[tiger.n].y) / (massiv[i+tmp.a1].y);
+
                {
            }
+
                    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)           //поиск конца совместной области определения
        {
 
             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,
+
                 del = h.love(massiv[k-1].x);
                                            F3.massiv[i].x,
+
                tmp.b2 = k-1;
                                            v.massiv[tiger.n + 1].x,
+
                tmp.b1 = del.n;
                                            v.massiv[tiger.n].y,
 
                                            v.massiv[tiger.n + 1].y )
 
                                            + v.massiv[i+tmp.a1 - tmp.k1].y;
 
 
             }
 
             }
 
             else
 
             else
                 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
+
                 if (massiv[k-1].x < h.massiv[k-1].x)
        }
 
 
 
        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];
+
                     del = h.love(massiv[k-1].x);
                     F3.massiv[j] = F3.massiv[j+1];
+
                     tmp.b2 = del.n;
                     F3.massiv[j+1] = temp;
+
                     tmp.b1 = k-1;
 
                 }
 
                 }
 
                 else
 
                 else
                if (F3.massiv[j].x == F3.massiv[j+1].x)
+
                    if (massiv[k-1].x == h.massiv[k-1].x)
                {
 
                    int l = j;
 
                    while (l < general)
 
 
                     {
 
                     {
                         F3.massiv[j].x = F3.massiv[j+1].x;
+
                         tmp.b2 = k-1;
                        l++;
+
                        tmp.b1 = k-1;
                    }
+
                    };
                    general--;
+
 
                 }
+
            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;                                    //возвращает первые и последние значения обеих функций и
 +
         }                                                   //их количества элементов
  
        for (int i = 0 ; i < general ; i++)
+
    //ПЕРЕГРУЗКА ОПЕРАТОРОВ
        {
 
  
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
+
    stars operator+ (stars & v)                            //сложение
        }
+
    {
 
+
        polyana tmp = prepare(v);
 
+
        int general = tmp.k1 + tmp.k2;                     //общее количество элементов обеих функций
         stars normalny(general);
+
         stars F3(general);                                 //создание объекта класса только по количеству элементов
         for (int i = 0; i < (general); i++)
+
         for (int i = 0 ; i < tmp.k1 ; i++)                 //заполнение первой части окончательного результата
 
         {
 
         {
             normalny.massiv[i].x = F3.massiv[i].x;
+
             F3.massiv[i].x = massiv[i+tmp.a1].x;
             normalny.massiv[i].y = F3.massiv[i].y;
+
             trees tiger = v.love(massiv[i+tmp.a1].x);
        }
+
            if (tiger.pol == true)                          //если значения по У в одной точке не совпадают, то интерполировать
        a = normalny.massiv[0].x;
+
            {
        b = normalny.massiv[general].x;
+
                F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
        return normalny;
+
                                          F3.massiv[i].x,
    }
+
                                          v.massiv[tiger.n + 1].x,
    };
+
                                          v.massiv[tiger.n].y,
 
+
                                          v.massiv[tiger.n + 1].y )
    trees love (double a)                                  //
+
                                          + massiv[i+tmp.a1].y;
    {
+
            }
        trees privet;
+
            else                                            //иначе, просто сложить значения
        for (int i = 0; i < k; i++ )
 
            if ((massiv[i].x < a)&& (a < massiv[i+1].x))
 
 
             {
 
             {
                 privet.n = i;
+
                 F3.massiv[i].y = v.massiv[tiger.n].y + massiv[i+tmp.a1].y;
                privet.pol = true;
 
                return privet;
 
 
             }
 
             }
             else
+
 
                 if (massiv[i].x == a)
+
        }
 +
        {
 +
          for (int i = tmp.k1  ; i < (general) ; i++)      //заполнение второй части окончательного результата
 +
        {
 +
            F3.massiv[i].x = v.massiv[i + tmp.a2 - tmp.k1].x;
 +
            trees tiger = love(v.massiv[i + tmp.a2 - tmp.k1].x);
 +
            if (tiger.pol == true)
 +
             {
 +
                 F3.massiv[i].y = pentagon  (v.massiv[tiger.n].x,
 +
                                            F3.massiv[i].x,
 +
                                            v.massiv[tiger.n + 1].x,
 +
                                            v.massiv[tiger.n].y,
 +
                                            v.massiv[tiger.n + 1].y )
 +
                                            + v.massiv[i+tmp.a1 - tmp.k1].y;
 +
            }
 +
            else
 +
                F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
 +
        }
 +
 
 +
        for (int i = 0; i < (general); i++)                  //сортировка
 +
        {
 +
            for (int j = 0; j < (general - 1); j ++)
 +
            {
 +
                dot temp;
 +
                if (F3.massiv[j].x > F3.massiv[j + 1].x)
 
                 {
 
                 {
                     privet.n = i;
+
                     temp = F3.massiv[j];
                     privet.pol = false;
+
                     F3.massiv[j] = F3.massiv[j + 1];
                     return privet;
+
                     F3.massiv[j + 1] = temp;
 
                 }
 
                 }
                 else
+
                 else                                       //если элементы совпадают, то нужно выбросить один из них
                 if (massiv[i+1].x == a)
+
                 if (F3.massiv[j].x == F3.massiv[j + 1].x)
 
                 {
 
                 {
                     privet.n = i+1;
+
                     int l = j;
                    privet.pol = false;
+
                    while (l < general)
                     return privet;
+
                    {
                 }
+
                        F3.massiv[l].x = F3.massiv[l + 1].x;
    }
+
                        F3.massiv[l].y = F3.massiv[l + 1].y;
 +
                        l++;
 +
                     }
 +
                    general--;
 +
                 }
 +
            }
 +
        }
  
  
    approx approximate ()                                  //функция аппроксимации
+
         stars normalny (general);                           //создание элемента класса по длине
    {
+
         for (int i = 0; i < (general); i++)
        approx hey;
 
         stars mattafix (double a, double b, double step, int k, int length);
 
        double sigmaX = 0;
 
        double sigmaY = 0;
 
        double sigmaXY = 0;
 
        double sigmaXsqrt = 0;
 
         for (int i = 0; i < length; i++)
 
 
         {
 
         {
          sigmaX += a + step * i;
+
            normalny.massiv[i].x = F3.massiv[i].x;
          sigmaY += b + i * 5;
+
            normalny.massiv[i].y = F3.massiv[i].y;
          sigmaXY += (a + step * i)*(b + i * 5);
 
          sigmaXsqrt += (a + step * i)*(a + step * i);
 
 
         }
 
         }
         hey.koefficientA = ((k * (sigmaXY) - (sigmaX*sigmaY))/(k*sigmaXsqrt - (sigmaX * sigmaX)));
+
         a = normalny.massiv[0].x;
         hey.koefficientB = ((sigmaY - hey.koefficientA*sigmaX)/k);
+
         b = normalny.massiv[general].x;
         return hey;
+
         return normalny;
 
 
 
 
 
     }
 
     }
};
+
    };
  
int main()
+
        stars operator* (stars & v)                         //умножение
{
+
     {
    int tyu;
+
         polyana tmp = prepare(v);
    stars function3;
+
         int general = tmp.k1 + tmp.k2;
    int firstnumber1;
+
         stars F3(tmp.k1 + tmp.k2);
    int firstnumber2;
+
         for (int i = 0 ; i < tmp.k1 ; i++)
    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:
+
             F3.massiv[i].x = massiv[i+tmp.a1].x;
             {  cout << "Vvedite pervy x" << endl;
+
             trees tiger = v.love(massiv[i+tmp.a1].x);
                cin >> firstnumber1;
+
            if (tiger.pol == true)
                 cout << "Vvedite posledniy x" << endl;
+
            {
                cin >> lastnumber1;
+
                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,      F3.massiv[i].x,
                cout << "Vvedite shag" << endl;
+
                                          v.massiv[tiger.n + 1].x,  v.massiv[tiger.n].y,
                cin >> step1;
+
                                          v.massiv[tiger.n + 1].y )* (massiv[i+tmp.a1].y);
                break;
 
 
             }
 
             }
             case 1:
+
             else
 
             {
 
             {
                 cout << "Vvedite pervy x" << endl;
+
                 F3.massiv[i].y = v.massiv[tiger.n].y * massiv[i+tmp.a1].y;
                cin >> firstnumber2;
 
                cout << "Vvedite posledniy x" << endl;
 
                cin >> lastnumber2;
 
                cout << "Vvedite shag" << endl;
 
                cin >> step2;
 
                break;
 
 
             }
 
             }
             case 2:
+
 
 +
        }
 +
        {
 +
             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)
 
             {
 
             {
                 stars function1 (firstnumber1, lastnumber1, step1);
+
                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
                function1.out();
+
                                            F3.massiv[i].x,
                 function1.outinfile ();
+
                                            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;
 +
        }
  
                stars function2 (firstnumber2, lastnumber2, step2);
+
        for (int i= 0; i < (general); i++)
                function2.out();
+
        {
                function2.outinfile ();
+
            for (int j = 0; j < (general - 1); j ++)
 
+
            {
                 function3 = function1 + function2;
+
                 dot temp;
                 function3.out();
+
                 if (F3.massiv[j].x > F3.massiv[j+1].x)
                function3.outinfile ();
+
                {
                break;
+
                    temp = F3.massiv[j];
            }
+
                    F3.massiv[j] = F3.massiv[j+1];
            case 3:
+
                    F3.massiv[j+1] = temp;
            {
+
                }
                 stars function1 (firstnumber1, lastnumber1, step1);
+
                else
                function1.out();
+
                 if (F3.massiv[j].x == F3.massiv[j+1].x)
                 function1.outinfile ();
+
                {
 +
                    int l = j;
 +
                    while (l < general)
 +
                    {
 +
                        F3.massiv[j].x = F3.massiv[j+1].x;
 +
                        l++;
 +
                    }
 +
                    general--;
 +
                 }
 +
            }
 +
        }
 +
 
 +
        for (int i = 0 ; i < general ; i++)
 +
        {
 +
 
 +
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
 +
        }
  
                stars function2 (firstnumber2, lastnumber2, step2);
 
                function2.out();
 
                function2.outinfile ();
 
  
                function3 = function1 * function2;
+
        stars normalny(general);
                function3.out();
+
        for (int i = 0; i < (general); i++)
                function3.outinfile ();
+
        {
                break;
+
            normalny.massiv[i].x = F3.massiv[i].x;
             }
+
            normalny.massiv[i].y = F3.massiv[i].y;
             case 4:
+
        }
 +
        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)
 
             {
 
             {
                 stars function1 (firstnumber1, lastnumber1, step1);
+
                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,       F3.massiv[i].x,
                function1.out();
+
                                          v.massiv[tiger.n + 1].x,   v.massiv[tiger.n].y,
                function1.outinfile ();
+
                                          v.massiv[tiger.n + 1].y )- massiv[i+tmp.a1].y;
 
 
                stars function2 (firstnumber2, lastnumber2, step2);
 
                function2.out();
 
                function2.outinfile ();
 
 
 
                function3 = function1 / function2;
 
                function3.out();
 
                function3.outinfile ();
 
                break;
 
 
             }
 
             }
             case 5:
+
             else
 
             {
 
             {
 +
                F3.massiv[i].y = v.massiv[tiger.n].y - massiv[i+tmp.a1].y;
 +
            }
  
                stars function1 (firstnumber1, lastnumber1, step1);
+
        }
                function1.out();
+
        {
                function1.outinfile ();
+
            for (int i = tmp.k1 ; i < (general) ; i++)
 
+
        {
                stars function2 (firstnumber2, lastnumber2, step2);
+
            F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
                function2.out();
+
            trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
                function2.outinfile ();
+
            if (tiger.pol == true)
 
+
             {
                function3 = function1 - function2;
+
                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
                function3.out();
+
                                            F3.massiv[i].x,
                function3.outinfile ();
+
                                            v.massiv[tiger.n + 1].x,
                break;
+
                                            v.massiv[tiger.n].y,
             }
+
                                            v.massiv[tiger.n + 1].y )
            case 6:
+
                                            + v.massiv[i+tmp.a1 - tmp.k1].y;
                 {
 
                    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;
 
         }
 
         }
    };
 
  
 +
        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--;
 +
                }
 +
            }
 +
        }
  
</syntaxhighlight>
+
        for (int i = 0 ; i < general ; i++)
</div>
+
        {
  
 +
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
 +
        }
  
  
 +
        stars normalny(general);
 +
        for (int i = 0; i < (general); i++)
 +
        {
 +
            normalny.massiv[i].x = F3.massiv[i].x;
 +
            normalny.massiv[i].y = F3.massiv[i].y;
 +
        }
 +
        a = normalny.massiv[0].x;
 +
        b = normalny.massiv[general].x;
 +
        return normalny;
 +
    }
 +
    };
  
 +
    stars operator/ (stars & v)                            //деление
 +
    {
 +
        polyana tmp = prepare(v);
 +
        int general = tmp.k1 + tmp.k2;
 +
        stars F3(tmp.k1 + tmp.k2);
 +
        for (int i = 0 ; i < tmp.k1 ; i++)
 +
        {
 +
            F3.massiv[i].x = massiv[i+tmp.a1].x;
 +
            trees tiger = v.love(massiv[i+tmp.a1].x);
 +
            if (tiger.pol == true)
 +
            {
 +
                F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,      F3.massiv[i].x,
 +
                                          v.massiv[tiger.n + 1].x,  v.massiv[tiger.n].y,
 +
                                          v.massiv[tiger.n + 1].y )/ (massiv[i+tmp.a1].y);
 +
            }
 +
            else
 +
            {
 +
                F3.massiv[i].y = (v.massiv[tiger.n].y) / (massiv[i+tmp.a1].y);
 +
            }
  
'''[[Лосева Татьяна]]'''
+
        }
+
        {
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.
+
            for (int i = tmp.k1 ; i < (general) ; i++)
 +
        {
 +
            F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
 +
            trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
 +
            if (tiger.pol == true)
 +
            {
 +
                F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
 +
                                            F3.massiv[i].x,
 +
                                            v.massiv[tiger.n + 1].x,
 +
                                            v.massiv[tiger.n].y,
 +
                                            v.massiv[tiger.n + 1].y )
 +
                                            + v.massiv[i+tmp.a1 - tmp.k1].y;
 +
            }
 +
            else
 +
                F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
 +
        }
  
'''Инструкция к программе:''' Начальная координата и шаг,для задания координат функций,передаются при вызове методов,создающих функции.Начальный шаг,шаг интерполяции,а так же количество выводимых координат заданы глобально.Поэтому просто запускайте программу, при желании поменяйте заданные
+
        for (int i= 0; i < (general); i++)
величины.
+
        {
 +
            for (int j = 0; j < (general - 1); j ++)
 +
            {
 +
                dot temp;
 +
                if (F3.massiv[j].x > F3.massiv[j+1].x)
 +
                {
 +
                    temp = F3.massiv[j];
 +
                    F3.massiv[j] = F3.massiv[j+1];
 +
                    F3.massiv[j+1] = temp;
 +
                }
 +
                else
 +
                if (F3.massiv[j].x == F3.massiv[j+1].x)
 +
                {
 +
                    int l = j;
 +
                    while (l < general)
 +
                    {
 +
                        F3.massiv[j].x = F3.massiv[j+1].x;
 +
                        l++;
 +
                    }
 +
                    general--;
 +
                }
 +
            }
 +
        }
  
Cкачать программу можно  [http://tm.spbstu.ru/Файл:Loseva.rar здесь]
+
        for (int i = 0 ; i < general ; i++)
 +
        {
  
<div class="mw-collapsible-content">
+
            cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
        }
#include <iostream>
 
  
using namespace std;
 
  
#define N 5//количество точек
+
        stars normalny(general);
 
+
        for (int i = 0; i < (general); i++)
const double l1 = 5;//задаём начальный шаг функций
+
        {
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;
 +
    }
 +
    };
 +
 
 +
    trees love (double a)                                  //
 +
    {
 +
        trees privet;
 +
        for (int i = 0; i < k; i++ )
 +
            if ((massiv[i].x < a)&& (a < massiv[i+1].x))
 +
            {
 +
                privet.n = i;
 +
                privet.pol = true;
 +
                return privet;
 +
            }
 +
            else
 +
                if (massiv[i].x == a)
 +
                {
 +
                    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 Func
 
{//класс,хранящий функцию,содержащий методы:печать,перегрузка,интерполяция,апроксимация
 
  
public:
+
    approx approximate ()                                   //функция аппроксимации
Func(int size) : size_(size), ax(new double[size]), by(new double[size])//создаём два массива,заполняем нулями
+
    {
{
+
        approx hey;
for (int i = 0; i< size_; i++)
+
        stars mattafix (double a, double b, double step, int k, int length);
{
+
        double sigmaX = 0;
ax[i] = 0;
+
        double sigmaY = 0;
by[i] = 0;   //все элементы обоих массивов обнуляются
+
        double sigmaXY = 0;
}
+
        double sigmaXsqrt = 0;
}
+
        for (int i = 0; i < length; i++)
 +
        {
 +
          sigmaX += a + step * i;
 +
          sigmaY += b + i * 5;
 +
          sigmaXY += (a + step * i)*(b + i * 5);
 +
          sigmaXsqrt += (a + step * i)*(a + step * i);
 +
        }
 +
        hey.koefficientA = ((k * (sigmaXY) - (sigmaX*sigmaY))/(k*sigmaXsqrt - (sigmaX * sigmaX)));
 +
        hey.koefficientB = ((sigmaY - hey.koefficientA*sigmaX)/k);
 +
        return hey;
 +
 
  
void print()//вывод на экран
+
    }
{
+
};
cout << "x: ";
 
for (int i = 0; i < size_; i++)
 
cout << ax[i] << " ";
 
cout << endl << "y: ";
 
for (int i = 0; i < size_; i++)
 
cout << by[i] << " ";
 
cout << endl;
 
}
 
  
Func &operator+(Func &f2)//функция перегрузки:cложение функций
+
int main()
{
+
{
Func *result = new Func(size_);//создаём результирующую функцию,равную сумме двух f2 и this
+
    int tyu;
for (int i = 0; i < size_; i++)
+
    stars function3;
{
+
    int firstnumber1;
result->ax[i] = this->ax[i];//суммируем координаты X
+
    int firstnumber2;
result->by[i] = f2.by[i] + this->by[i];//суммируем координаты Y
+
    int lastnumber1;
}
+
    int lastnumber2;
cout << "Sum f(x)=f1+f2:" << endl;//выводим на экран сумму функций
+
    int step1;
result->print();
+
    int step2;
return *result;
+
    while (true)
}
+
    {
  
void Int(double L) //метод Интерполяции
+
        cout << "Input 0 - vvedite parametry pervoy funkcii"<< endl;
{
+
        cout << "Input 1 - vvedite parametry vtoroy funkcii"<< endl;
int M = (this->ax[this->size_ - 1] - this->ax[0]) / L + 1; //M- количество элементов массива с координатами интерполирующей функции;
+
        cout << "Input 2 - slozhenie"<< endl;
Func result = Func(M);//cоздаём функцию,в кторой будет храниться результат интерполяции
+
        cout << "Input 3 - umnozhenie"<< endl;
cout << "M =" << M << endl;//выводим M для проверки
+
        cout << "Input 4 - delenie"<< endl;
cout << "Interpolation: " << endl;
+
        cout << "Input 5 - vychitanie"<< endl;
int t;
+
        cout << "Input 6 - aproximate"<< endl;
for (int i = 1; i < M; i++)
+
        cin >> tyu ;
{
 
result.ax[0] = this->ax[0];
 
result.ax[i] = result.ax[i - 1] + L;//интерполируем Х,прибавляя шаг к каждому предыдущему элементу
 
t = (result.ax[i - 1] - result.ax[0]) / l1;//считаем номер элемента,"левого" от искомого
 
  
                      //интерполируем Y по формуле
+
        switch (tyu)
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]);
+
        {
 +
            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 ();
  
result.print();//выводим результат
+
                function3 = function1 + function2;
}
+
                function3.out();
 +
                function3.outinfile ();
 +
                break;
 +
            }
 +
            case 3:
 +
            {
 +
                stars function1 (firstnumber1, lastnumber1, step1);
 +
                function1.out();
 +
                function1.outinfile ();
  
void aprox()//Апроксимация
+
                stars function2 (firstnumber2, lastnumber2, step2);
{
+
                function2.out();
double a=0;
+
                function2.outinfile ();
          for(int i=0;i<size_;i++)//считаем сумму x
 
  a=this->ax[i]+a;
 
       
 
  
double b=0;
+
                function3 = function1 * function2;
for(int i=0;i<size_;i++)//считаем сумму y
+
                function3.out();
b=this->by[i]+b;
+
                function3.outinfile ();
+
                break;
 +
            }
 +
            case 4:
 +
            {
 +
                stars function1 (firstnumber1, lastnumber1, step1);
 +
                function1.out();
 +
                function1.outinfile ();
  
double c=0;
+
                stars function2 (firstnumber2, lastnumber2, step2);
for(int i=0;i<size_;i++)//считаем сумму квадратов x
+
                function2.out();
c=(this->ax[i])*(this->ax[i])+c;
+
                function2.outinfile ();
 
  
double d=0;
+
                function3 = function1 / function2;
for(int i=0;i<size_;i++)//считаем сумму xy
+
                function3.out();
d=(this->ax[i])*(this->by[i])+d;
+
                function3.outinfile ();
+
                break;
 +
            }
 +
            case 5:
 +
            {
  
//затем решаем систему для у=kx+m
+
                stars function1 (firstnumber1, lastnumber1, step1);
//(1)c*k+a*m=d
+
                function1.out();
//(2)a*k+size_*m=b;
+
                function1.outinfile ();
//k=(d-am)/с
 
//подставим в (2)
 
double m;
 
m=(b*c-a*d)/(c*size_-a*a);
 
double k;
 
k=(d-a*m)/c;
 
cout<<"aproximacia :: ";
 
cout<<"y="<<k<<"x+"<<m<<endl;
 
  
}
+
                stars function2 (firstnumber2, lastnumber2, step2);
 +
                function2.out();
 +
                function2.outinfile ();
  
 +
                function3 = function1 - function2;
 +
                function3.out();
 +
                function3.outinfile ();
 +
                break;
 +
            }
 +
            case 6:
 +
                {
 +
                    approx you;
 +
                    function3.approximate();
 +
                    outfile.open ("meow", ios :: app);
 +
                    outfile << "Y = "<< you.koefficientA <<"* x + "<<you.koefficientB << endl;
 +
                    outfile << endl;
 +
                    outfile.close();
  
double *ax;
 
double *by;
 
  
private:
+
                }
int size_;//размер массива
+
            }
};
+
        }
 +
    };
  
  
 +
</syntaxhighlight>
 +
</div>
  
 +
'''[[Капитанюк Светлана]]'''
  
class Cord//класс,создающий и хранящий значение функций
+
'''Описание программы:''': программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции. функции хранятся в программе как массив точек, заданных с определенным шагом по X на заданном отрезке. Функции заданы автоматически, поэтому нет необходимости вводить каждый промежуток, нужно ввести только начало, конец и шаг. Далее пользователю на выбор будет представлено несколько операций с функциями, такие как: сложение, вычитание, умножение и деление функции одну на другую. Если функции имеют различный шаг, топеред этимони интерполируются. Так же в программе предусмотрена аппроксимация.
{
 
public:
 
Cord(double x0, double s) :x0(x0), s(s)//x0-начальная координата;s-шаг
 
{
 
}
 
  
void Fyx1(Func func)//метод,считающий координаты нашей функции y=x
 
{
 
int i;
 
func.ax[0] = x0;
 
for (i = 1; i < N; i++)//считаются иксы
 
{
 
func.ax[i] = x0 + s;
 
x0 = func.ax[i];
 
}
 
for (i = 0; i<N; i++)
 
func.by[i] = func.ax[i];//считаем координаты у
 
cout << "f1 :" << endl;
 
func.print();
 
cout << endl;
 
}
 
 
void Fyx2(Func func)//метод,считающий координаты нашей функции y=x+1
 
{
 
int i;
 
func.ax[0] = x0;
 
for (i = 1; i<N; i++)//считаем иксы
 
{
 
func.ax[i] = x0 + s;
 
x0 = func.ax[i];
 
}
 
for (i = 0; i<N; i++)
 
func.by[i] = func.ax[i] + 1;//считаем игрики
 
cout << "f2 :" << endl;
 
func.print();
 
cout << endl;
 
}
 
 
private:
 
double x0;//начальная координата
 
double s;//шаг
 
};
 
 
int main()
 
{
 
Func f1(N);//создание функции f1
 
Func f2(N);//создание f2
 
Cord s1(0, l1);//cоздаём объект s1
 
Cord s2(0, l1);//cоздаём объект s2
 
s1.Fyx1(f1);//задаём координаты 1ой функции
 
s2.Fyx2(f2);//задаём координаты 2ой функции
 
 
      //сложение функций:
 
 
Func f3 = f2 + f1;//есть тоже ,что и Func f3 = f2.operator+(f1);
 
 
f1.Int(l2);//Интерполируем f1 с новым шагом l2
 
f1.aprox();//Апроксимируем f1
 
 
getchar();
 
return 0;
 
}
 
 
</syntaxhighlight>
 
</div>
 
  
 +
Скачать можно  [http://tm.spbstu.ru/File:Function_02.zip тут].
  
 +
'''[[Киселёв Лев]]'''
 +
'''Описание программы''':программа позволяет интерполировать и аппроксимировать значения функции, а также складывать две функции, используя перегрузку.
  
 +
Скачать можно [[http://mech.spbstu.ru/File:Interpol.rar здесь]]
  
 
'''[[Козловская Анна]]'''
 
'''[[Козловская Анна]]'''
Строка 1444: Строка 1342:
 
Скачать можно  [http://tm.spbstu.ru/File:project1.rar тут].
 
Скачать можно  [http://tm.spbstu.ru/File:project1.rar тут].
  
 +
'''[[Лебедев Станислав]]'''
  
 +
'''Описание программы''': программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.
  
 +
'''Пояснения к алгоритму''':
 +
#  Прочитанные из файла функции нужно отсортировать.
 +
#  Найти совместную область определения, то есть, найти множество пересечения областей определения функций, над которыми совершается операция.
 +
#  Создать третью функцию, со следующими свойствами : область определения состоит только из точек, принадлежащих совместной области определения, каждая точка области значений является результатом нужной операции над точкой области значений одной из функций и, либо интерполированной точкой по другой функции, либо, если есть возможность, точным значением из ее области значений.
  
'''[[Сюрис Александр]]'''
+
Скачать можно  [http://tm.spbstu.ru/Файл:Функции.rar тут].
Задаются две функции с разными шагами и начальными и конечными значениями.  Аппроксимирует одну функцию по шагу другой и складывает/умножает/вычитает/делит их
 
  
Скачать можно  [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 тут].
 
  
<div class="mw-collapsible-content">
+
<div class="mw-collapsible mw-collapsed" style="width:100%" ><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 <vector>
+
#include <math.h>
#include<math.h>
+
#include <cstring>
 +
#include <cmath>
 +
#include <malloc.h>
 +
#include <fstream>
  
 
using namespace std;
 
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));
 
  
        vector<double> v1;//вектор, содержащий проинтерполированную функцию
+
double base(double x)                                        //базовая функция ( если задавать через шаг и начальный х
            for(int i=0; i<=(en-st)/d; i++)
+
{
                v1.push_back(a*(st+i*d)+b);//добавление значений проинтерполированной ф-ции с шагом другой функции
+
    return x;
        return f(_st,_en,_d,v1);
+
}
  
    }
+
struct ap                                                  //две одинаковые структуры это нехорошо,коненчо,но зато наглядно...
 
+
{
    f operator +(f x){//оператор сложения
+
    double k,b;
        double _en,_st,_d;
+
};
        _en=min(en,x.en); //поиск области пересечения
 
        _st=max(st,x.st);
 
        if (_en>_st){//проверяем, пересекаются ли функции
 
            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(){ //поиск противоположной функции
+
struct fun                                                  //один столбик в таблице функции
        for (int i=0; i<=(en-st)/d; i++)
+
{
            v[i]=(-1)*v[i];
+
    double x,y;
        return *this;
+
};
    }
 
  
    f operator - (f x){ //разность функций
+
struct sf                                                  //структура нужная, для возражеия значений из функции "prepare" класса F
        return(*this + x.prot());
+
{
     }
+
    int i1,i2,e1,e2;
 +
     double glength, gfirstx, glastx;
 +
};
  
f operator *(f x){//оператор умножения
+
double intr(double x1,double x2,double x,double y1,double y2) // линенейная интерполяция
        double _en,_st,_d;
+
{
        _en=min(en,x.en); //поиск области пересечения
+
    return ( ((x-x1)/(x2-x1)) * (y2-y1) + y1 );
        _st=max(st,x.st);
 
        if (_en>_st){//проверяем, пересекаются ли функции
 
            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 obr(){
 
  for (int i=0; i<=(en-st)/d; i++)
 
            v[i]=1/v[i];
 
        return *this;
 
 
}
 
}
  
f operator /(f x){
+
ap aproks(fun b [],int n)                                      //линейная аппроксимация
return(*this*x.obr());
+
{
}
+
    ap r;
 +
    double xy = 0,x = 0,y = 0,sqx = 0,xsq = 0;
 +
    for (int i = 0; i < n; i++)                                 //вычисление коэффицентов
 +
    {
 +
        xy  += b[i].x*b[i].y;
 +
        x  += b[i].x;
 +
        y  += b[i].y;
 +
        sqx += b[i].x*b[i].x;
 +
        xsq += b[i].x;
 +
    }
 +
    xsq *= xsq;
  
     void vivod(){ //вывод
+
     r.k = (n*xy - x*y)/(n*sqx - xsq);                      //использование формул
     for(int i=0; i<v.size(); i++)
+
     r.b = (y - r.k*x)/n;
        cout<<v[i]<<" ";
+
    return r;
 +
}
  
    }
+
class F
};
+
{
int main(){
+
private:
     setlocale(LC_ALL, "Russian");
+
     int length;
     double a,b,a1,b1,d,d1,t;
+
     double firstx, step, lastx;
     int o;
+
     fun *a;
    cout << "Введите начала и конец отрезка и дельту: ";
+
public:
     cin>>a>>b>>d;
+
     F(){}
     int amount=(b-a)/d+1,amount2;
+
     F(int l,double f,double s)                             //конструктор, создающий фунцию по длине,первоиу элементу,шагу по х, y вычисляется по базовой функции
    vector<double>x;
 
    cout << "Введите " << amount << " значений функции на данном интервале:";
 
    for (int i=0; i<amount; i++)
 
 
     {
 
     {
         cin>>t;
+
         if (l >= 0)
         x.push_back(t);
+
          a = new fun [l];
    }
+
         firstx = f;
 
+
        length = l;
    cout << "Проделаем ровно то же самое для 2 функции ";
+
        step = s;
    cout << "Введите начала и конец отрезка и дельту: ";
+
        lastx = firstx+(length - 1)*step;
    cin >> a1 >> b1 >> d1;
 
  
    amount2=(b1-a1)/d1+1;
 
    vector<double>y;
 
    cout << "Введите " << amount2 << " значений функции на данном интервале:";
 
    for (int i=0; i<amount2; i++)
 
    {
 
        cin>>t;
 
        y.push_back(t);
 
    }
 
    f g(a,b,d,x);
 
    f h(a1,b1,d1,y);
 
  
    cout<<"Выберете дейстивя с функциями: +, -, *, \ " << endl;
+
        for (int i = 0;i < length; i ++)
    cout<<"Введите число, соответсвующее порядковому номеру операции(1-4) - ";
+
         {
    cin>>o;
+
            a[i].y = base(firstx + i*step);
    if(o==1){              //по невыясненным причинам одновременно написанные слева идущие if -ы не работают,
+
            a[i].x = firstx + i*step;
         cout<<"Сумма:";    //но если заккоментить их и менять знак + в скобке на другие, то все работает
+
        }
        (g+h).vivod();
 
  
 
     }
 
     }
  
     if(o==2){
+
     F (fun b[],int l)                                   //конструктор для создания фунции с уже известными областями определния и значений
         cout<<"Разность:"
+
    {
         (g-h).vivod();
+
         length = l;
 +
        a = new fun [l];
 +
         for (int i = 0; i < l;i++)
 +
            a[i] = b[i];
  
    }
+
        for (int i = 0; i < l;i++)
 
+
            for (int j = 0; j < (l - 1); j++)
    if(o==3){
+
                if (a[j].x > a[j + 1].x)
        cout<<"Произведение:"
+
                {
        (g*h).vivod();
+
                    fun tmp = a[j];
 +
                    a[j] = a[j + 1];
 +
                    a[j + 1] = a[j];
 +
                }
  
 +
        firstx = a[0].x;
 +
        lastx = a[length - 1].x;
 +
    }
  
 +
    void addpar (double k, double b, int l, fun z[] )                          //позволяет создать и заполнить переданным массивом поле объекта класса
 +
    {
 +
        a = new fun [l];
 +
        for (int i = 0; i < l; i++)
 +
        {
 +
            a[i].y = k*z[i].x + b;
 +
            a[i].x = z[i].x;
 +
        }
 +
        length = l;
 
     }
 
     }
  
    if(o==3){
+
    double getelx(int i)                               //возращает значение из поля "х" iого элемента
        cout<<"Отношение:"
+
    {
         (g/h).vivod();
+
         return a[i].x;
 
     }
 
     }
  
  
}
+
    double getely(int i)                              //возращает значение из поля "х" iого элемента
 
+
    {
</syntaxhighlight>
+
        return a[i].y;
</div>
+
    }
  
 +
    int getlength()                                //возращает размер области определения функции(в точках)
 +
    {
 +
        return length;
 +
    }
  
 +
    void FOut()                                    //выводит функцию на экран
 +
    {
 +
      cout << "  x        y" << endl;
 +
      for (int i = 0;i < length; i ++)
 +
          cout << "  " << a[i].x << "        " << a[i].y << endl;
 +
      cout << endl;
 +
    }
  
  
 
+
    int pfind(double x)const                        //возращает либо номер элемента,идущщий перед элементом, большим,чем х; в случае нахождения равного, возращает число, противоположное номеру следующего элемента(иначе может вернуться нуль,а нуль знака не имееет)
 
 
'''[[Андреева Полина]]'''
 
 
 
'''Инструкция к программе:''' пользователь должен ввести начало, конец и шаг. Создается две функции. Затем на экране появляется один из знаков арифметических действий. Пользователь выбирает один из знаков. Создается третья функция. Пользователь вводит второй шаг. Функция интерполируется по этому новому шагу, а затем аппроксимируется.
 
'''Краткое описание алгоритма :''' в классе создается две функции(с помощью массивов). Так же в классе есть такие методы: перегрузка арифм операций, интерполяция, аппроксимация, вывод массивов на экран и их сохранение в файл. Сначала создается два массива для функций. Затем  с помощью перегрузки эти два массива складываются/умножаются/делятся/вычитаются и записываются опять в этот массив. В методе перегрузки сразу вызывается интерполяция и аппроксимация.
 
[http://tm.spbstu.ru/Файл:Function.rar Программа]
 
<div class="mw-collapsible-content">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
 
 
#include <iostream>
 
#include <fstream>
 
#include "math.h"
 
using namespace std;
 
class func
 
{
 
private:
 
    double *mass1, *mass, *masss ;
 
    double  AmountDouble, Begin, End, Step, Step2;
 
public:
 
    int  AmountInt;
 
    func ( double _Begin, double _End, double _Step ):Begin(_Begin), End(_End), Step(_Step)
 
 
     {
 
     {
        AmountDouble=((End-Begin)/Step)+1;///количество точек с данным шагом
+
         for (int i = 0; i < length-1; i++ )
        AmountInt=static_cast<int>(AmountDouble);///так как количество это целое число, то округляем
 
 
 
    }
 
 
 
    void massiv1() ///создание первой функции х^3
 
    {
 
        mass=new double[AmountInt];
 
         for (int l=0; l<AmountInt; l++)
 
 
         {
 
         {
             mass[l] =pow((l*Step+Begin),3);
+
             if (((a[i].x < x) && (a[i + 1].x > x)))
 +
                return (i + 1);
 +
            else
 +
                // чтобы иметь возможность проанализировать полученное значение функции,мы должны понимать, было найденно равное или промежуточное значение. "флагом" равных значений является знак минус,но так у нуля нет знака,то приходиться все сдвигать на 1
 +
                if (a[i].x == x)
 +
                  return -(i + 1);
 +
                else
 +
                    if (a[i + 1].x == x)
 +
                        return -(i + 2);
 
         }
 
         }
        cout << "y=x^3 \n";
+
//        cerr << "fail!!" << endl;
 +
        return -1;
 
     }
 
     }
     void massiv2() ///создание второй функции sin(x)
+
 
 +
     sf prepare(F &x)const                                      //"подготовка" функций к бинарной операции (нахождение совместной области определения
 
     {
 
     {
         mass=new double[AmountInt];
+
         sf r;
         for (int l=0; l<AmountInt; l++)
+
         if (a[0].x > x.a[0].x)
 
         {
 
         {
             mass[l] =sin(l*Step+Begin);
+
             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;
 
         }
 
         }
         cout << "y=sin(x) \n";
+
         else
    }
 
 
 
    void interpolation(double __Begin, double __End,  double __Step)
 
    {
 
 
 
        double NewAmount=((__End-__Begin)/__Step) + 1;///количество точек для нового шага
 
        int NewAmountInt=static_cast<int>(NewAmount);
 
        for (int i=0; i<NewAmountInt; i++)///i-это точки функции с новыми шагами
 
 
         {
 
         {
             mass1 = new double[NewAmountInt];
+
             r.gfirstx = x.a[0].x;
            double x = i*__Step+__Begin;///значения х в новых точках
+
             double k = pfind(x.a[0].x);
             double x0=(static_cast<int>((x-__Begin)/Step)) * Step+__Begin;///значение х в точке интерполяции
+
             if (k < 0)
            ///стоящей ДО новой точки
+
                r.i1 = -k - 1;
            double x1=x0+Step;///точка интерполяции ПОСЛЕ новой точки, т.е к предыдущей прибавляем СТАРЫЙ шаг
+
             else
             int i0=(static_cast<int>((x-__Begin)/Step));///это нужно для массива, значение массива в i0 соответстует значению функции в x0
+
                r.i1 = (k - 1) + 1;
            int i1=i0+1;
+
             r.i2 = 0;
             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++)
 
 
         {
 
         {
             x=i*__Step+__Begin;///такие значения принимает x в точках по порядку i
+
             r.glastx = a[length - 1].x;
             SumXMass=SumXMass+x*mass[i];
+
             r.e1 = length - 1;
             SumX=SumX+x;
+
             double k = x.pfind(r.glastx);
             SumMass=SumMass+mass[i];
+
             if (k < 0)
             SumXX=SumXX+x*x;
+
                r.e2 = -k - 1;
 
+
             else
 +
                r.e2 = (k - 1) - 1;
 
         }
 
         }
        double a=(SumXMass*AmountInt-SumX*SumMass)/(AmountInt*SumXX-SumX*SumX);
+
         else
        double b=(SumMass-a*SumX)/AmountInt;
 
        if (b>0)
 
            cout<<"approximation "<<a<<"*x+"<<b<<endl;
 
         else if (b<0)
 
            cout<<"approximation "<<a<<"*x"<<b<<endl;
 
 
 
        for (int i=0; i<AmountInt; i++)
 
 
         {
 
         {
             mass1[i] = a*(i*__Step+__Begin)+b;///такие значения принимает апроксимация
+
             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;
 
         }
 
         }
         delete[] mass;
+
         r.glength = length + x.length - r.i1 - (length - (r.e1 + 1)) - r.i2 - (x.length - (r.e2 + 1));
        mass=mass1;
 
        output();///вывод на экран
 
        SaveFile("approximation.txt");///сохранение в файл
 
        cout<<"end of appox";
 
  
 +
        return r;
 
     }
 
     }
  
     func operator+( func f)///перегрузка оператора +
+
     void ad (fun b[],int l)                                 //присвоить массиву объекта класса F значения массива b
 
     {
 
     {
         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];
+
         firstx = a[0].x;
         }
+
         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;
 
     }
 
     }
  
     func operator-( func f)
+
     F operator +(F &x) const                              //сложение двух функций
 
     {
 
     {
         func newmass(Begin, End, Step);
+
         int i1, e1, i2, e2, kk = 0;
         masss=new double[AmountInt];
+
         double gfirstx, glastx, glength;
         for (int i=0; i<AmountInt; i++)
+
 
 +
         if (((x.lastx < firstx) && (x.firstx < firstx)) || ((lastx < x.firstx) && (firstx < x.firstx)))
 
         {
 
         {
             masss[i] = mass[i] - f.mass[i];
+
             cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
 +
            F fl(-1,0,0);
 +
            return fl;
 
         }
 
         }
         delete [] mass;
+
         sf r = prepare(x);
        mass = masss;
+
         F tmp(r.glength,r.gfirstx,r.glastx);
        output();
+
         for (int i = 0; i <= (r.e1 - r.i1); i++)
         SaveFile("f3.txt");
+
         {
         cout<<"enter new step";
+
            tmp.a[i].x = a[i + r.i1].x;           //поправка,введенная таким образом,чтобы номер,с которого начинается отсчет был первым в новой области определения
         cin>>Step2;
+
            int ii = x.pfind(tmp.a[i].x);
        cout<<"interpolation: ";
+
            if (ii < 0)
        interpolation(Begin,End,Step2);
+
                tmp.a[i].y = x.a[-ii - 1].y + a[i + r.i1].y;
        cout<<" approximation: ";
+
            else
        approximation(Begin,End,Step2);
+
                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;
        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++)
 
 
         {
 
         {
             masss[i] = mass[i] / f.mass[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 --;
 +
            }
 
         }
 
         }
         cout << " division: \n ";
+
 
        delete [] mass;
+
         for (int i = 0; i < glength; i++)
        mass = masss;
+
            for (int j = 0; j < glength - 1; j++)
        output();
+
            if (tmp.a[j].x > tmp.a[j + 1].x)
        SaveFile("f3.txt");
+
            {
        cout<<"enter new step";
+
                fun t = tmp.a[j];
        cin>>Step2;
+
                tmp.a[j] = tmp.a[j + 1];
        cout<<"interpolation: ";
+
                tmp.a[j + 1] = t;
        interpolation(Begin,End,Step2);
+
            }
        cout<<" approximation: ";
+
 
        approximation(Begin,End,Step2);
+
         return tmp;
         return newmass;
+
}
    }
+
 
     func operator*( func f)
+
     F operator *(F & x) const                                        //умножение двух функций
 
     {
 
     {
         func newmass(Begin, End, Step);
+
         int i1, e1, i2, e2, kk = 0;
         masss=new double[AmountInt];
+
         double gfirstx, glastx, glength;
         for (int i=0; i<AmountInt; i++)
+
 
 +
         if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
 
         {
 
         {
             masss[i] = mass[i] * f.mass[i];
+
             cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
 +
            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++)
 
 
         {
 
         {
             cout << "y("<<i<< ") = " << mass[i] <<endl;
+
             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++)
 
 
 
 
    void SaveFile(char filename[])///сохранение функции в файл
 
    {
 
        std::ofstream fout(filename);
 
         for (int l=0; l<AmountInt; l++)
 
 
         {
 
         {
             fout<<l<<" "<<mass[l]<<" \n";
+
             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 --;
 +
            }
 
         }
 
         }
  
         fout.close();
+
         for (int i = 0; i < glength; i++)
    }
+
            for (int j = 0; j < glength - 1; j++)
};
+
            if (tmp.a[j].x > tmp.a[j + 1].x)
 +
            {
 +
                fun t = tmp.a[j];
 +
                tmp.a[j] = tmp.a[j + 1];
 +
                tmp.a[j + 1] = t;
 +
            }
  
 +
        return tmp;
 +
    }
  
 +
    F operator ^(F & x) const                                  //возведение функции слева от оператора в степень функции справа от оператора
 +
    {
 +
        int i1, e1, i2, e2, kk = 0;
 +
        double gfirstx, glastx, glength;
  
int main()
+
        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;
 +
        }
  
    double Begin1, End1, Step1, Step2;
+
        sf r = prepare(x);
    cout<<" enter the beginning of the  function ";
+
        F tmp(r.glength,r.gfirstx,r.glastx);
    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);///создание первой функции
+
        for (int i = 0; i <= (r.e1 - r.i1); i++)
    f1.massiv1();
+
        {
    f1.output();
+
            tmp.a[i].x = a[i + r.i1].x;
    cout<<"\n ";
+
            int ii = x.pfind(tmp.a[i].x);
    f1.SaveFile("f1.txt");
+
            if (ii < 0)
 
+
                tmp.a[i].y = pow(x.a[-ii - 1].y, a[i + r.i1].y);
    func f2(Begin1,End1,Step1);///создание второй функции
+
            else
    f2.massiv2();
+
                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);
    f2.output();
+
        }
    cout<<"\n ";
+
        for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
    f2.SaveFile("f2.txt");
+
        {
    cout<<"\n";
+
            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 --;
 +
            }
 +
        }
  
    func f3(Begin1,End1,Step1);
+
        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;
 +
            }
  
    cout<<" \n \n choose 1 - sum , 2 - subtract, 3 - division, 4 - multiply \n";///выбор операции
+
         return tmp;
    int z;
 
    cin>>z;
 
    switch (z)
 
    {
 
    case 1:
 
    {
 
         f3=f1+f2;///сумма функций
 
        break;
 
    }
 
    case 2:
 
    {
 
        f3=f1-f2;
 
        break;
 
    }
 
    case 3:
 
    {
 
        f3=f1/f2;
 
        break;
 
    }
 
    case 4:
 
    {
 
        f3=f1*f2;
 
        break;
 
 
     }
 
     }
 +
};
 +
 +
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;
  
     default :
+
     while(true)
 
     {
 
     {
         cout<<"NOOOOO";
+
    start :
         break;
+
        system("cls");
    }
+
         cout << "1 - Vvesti 1uu func"           << endl;
    };
+
         cout << "2 - Vvesti 2uu func"            << endl;
    return 0;
+
        cout << "3 - Sloshit'"                  << endl;
}
+
        cout << "4 - Umnozhit'"                  << endl;
 
+
        cout << "5 - Vozvesti v stepen'"        << endl;
 
+
        cout << "6 - Aproximirovat'"             << endl;
</syntaxhighlight>
+
        cout << "7 - Zapics' v file func"       << endl;
</div>
+
        cout << "8 - Zapics' v file aprok fun"   << endl;
 
+
        cout << "0 - Vihod"                     << endl;
 
+
        cin  >> vc;
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
        switch (vc)
'''[[Белоусова Екатерина]]'''
+
        {
 
+
            case '0':
'''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем пользователь выбирает одну из арифметических операций, которую он хочет применить к этим функциям. Создается третья функция. После пользователь вводит второй шаг для интерполяции. Третья функция интерполируется по новому шагу, а затем аппроксимируется.
+
                return 0 ;
 
+
            case '1':
'''Краткое описание алгоритма''': в классе при помощи массива создаются две функции, с которыми потом работает программа. Эти функции перегружаются операторами арифметических операций, где затем полученная новая функция интерполируется и аппроксимируется.
+
                {
 
+
                system("cls");
Скачать программу можно по ссылке  [http://tm.spbstu.ru/Файл:задача_2.zip].
+
                strcpy(s,"");
 
+
                delete []a;
<div class="mw-collapsible-content">
+
                a = NULL;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
                cout << "Vvedite imya fila" << endl;
#include <iostream>
+
                cin >> s;
#include <locale.h>
+
                strcat(s, ".txt");
#include <math.h>
+
                infile.open(s);
#include <fstream>
+
                infile >> n;
#include<iomanip>
+
                a = new fun [n];
 
+
                for(int i = 0; i < n; i ++)
using namespace std;
+
                    infile >> a[i].x >> a[i].y;
 
+
                f5.ad(a,n);
class functya ///создаем класс функции
+
                f5.FOut();
{
+
                infile.close();
 
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
private: ///объявляем тип переменных в привате
+
                cin >> ce;
    double *mass, *mass1, *mass2; ///*mass, *mass1, *mass2 -определение двумерного массива
+
                while (true)
    double start, ending, step, step2, amountdouble; ///start-начало, ending-конец, step-шаг, amountdouble-количество точек (типа double)
+
                if (ce == 'b')
 
+
                    goto start;
public: ///объявляем тип переменных в паблике
+
                }
    int amount; ///amoun-количество точек (типа int)
+
            case '2':
 
+
                {
functya (double _start, double _ending, double _step):start(_start),ending(_ending),step(_step) ///создаем конструктор функции с объявлением переменных
+
                system("cls");
{
+
                strcpy(s,"");
 
+
                delete []a;
    amountdouble=((ending-start)/step)+1; ///подсчитываем количество точек с заданым шагом
+
                a = NULL;
    amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
+
                cout << "Vvedite imya fila" << endl;
 
+
                cin >> s;
}
+
                strcat(s, ".txt");
 
+
                infile.open(s);
void massiv1 () ///создаем функцию массива
+
                infile >> n;
{
+
                a = new fun[n];
 
+
                for(int i = 0; i < n; i ++)
    mass=new double[amount]; ///создаем двумерный массив
+
                    infile >> a[i].x >> a[i].y;
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
+
                f6.ad(a,n);
    {
+
                f6.FOut();
        mass[l]= pow((l*step+start),3); ///при помощи массива задаем функцию с которой будем работать
+
                infile.close();
    }
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
    cout<< "\n";
+
                cin >> ce;
}
+
                while (true)
 
+
                if (ce == 'b')
void massiv2 () ///создаем функцию массива
+
                    goto start;
{
+
                }
 
+
            case '3':
    mass=new double[amount]; ///создаем двумерный массив
+
                system("cls");
    for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
+
                f5.FOut();
    {
+
                f6.FOut();
        mass[l]= pow((l*step+start),2); ///при помощи массива задаем функцию с которой будем работать
+
                f7 = f5 + f6;
    }
+
                f7.FOut();
    cout<< "\n";
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
 
+
                cin >> ce;
}
+
                while (true)
 
+
                if (ce == 'b')
void interpol (double __start, double __ending, double __step) ///создаем функцию интерполяция с определением переменных
+
                    goto start;
{
+
            case '4':
 
+
                system("cls");
    double amount1=((__ending-__start)/__step)+1; ///определяем тип и подсчитываем новое количество точек с новым шагом
+
                f5.FOut();
    int amounti=static_cast<int>(amount1); ///преобразуем количество из типа double к типу int
+
                f6.FOut();
 
+
                f7 = f5 * f6;
    for (int i=0; i<amounti; i++) ///создаем цикл от 0 до amounti-нового количества точек
+
                f7.FOut();
    {
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
 
+
                cin >> ce;
        mass1=new double[amounti];
+
                while (true)
        double x = i*__step+__start; ///определяем тип и расчитываем координату Х
+
                if (ce == 'b')
        double x0=(static_cast<int>((x-__start)/step)) * step+__start;///определяем тип и расчитываем координату х
+
                    goto start;
                                                                      ///в интерполирующейся точке, которая стоит до новой точки
+
            case '5':
        double x1=x0+step;///определяем тип и расчитываем координату х1 прибавляя к предыдущей точке шаг
+
                system("cls");
        int i0=(static_cast<int>((x-__start)/step));///определяем значение массива в i0 соответстующей значению функции в x0
+
                f5.FOut();
        int i1=i0+1;
+
                f6.FOut();
        mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
+
                f7 = f5 ^ f6;
        cout << "Х="<<i<<setw(10)<< "У= " << mass1[i] <<endl<<endl; ///выводим интерполяцию на экран
+
                f7 = f5 ^ f6;
        ofstream fout("interpol.txt",ios::app);///сохраняем в файл
+
                f7.FOut();
        fout<< "Х="<<i<<setw(10)<< "У="<<mass1[i]<<" \n";
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
        fout.close();
+
                cin >> ce;
 
+
                while (true)
    }
+
                if (ce == 'b')
 
+
                    goto start;
    amount=amounti;
+
            case '6':
    delete []mass;
+
            {
    mass = mass1;
+
                system("cls");
 
+
                ap tmp = aproks(f7.geta(), f7.getlength());
}
+
                f8.addpar(tmp.k, tmp.b, f7.getlength(), f7.geta());
 
+
                f8.FOut();
void aprocsimation(double __start, double __ending, double __step) ///создаем функцию апроксимация с определением переменных
+
                cout << "Nazhmite \"b\" chotibi viti" << endl;
{
+
                cin >> ce;
 
+
                while (true)
    int N=amount; ///определяем тип и значение переменной N (равна количеству точек с заданным шагом)
+
                if (ce == 'b')
    double SumXY=0; ///определяем тип и значение переменной SumXY ( сумма (Х*У) )
+
                    goto start;
    double SumX=0; ///определяем тип и значение переменной SumX ( сумма Х )
+
            }
    double SumY=0; ///определяем тип и значение переменной SumУ ( сумма У )
+
            case '7':
    double Sum_Xkv=0; ///определяем тип и значение переменной Sum_Xkv ( сумма (Х*Х) )
+
            {
    double Xi; ///определяем тип переменной Xi
+
                system("cls");
 
+
                strcpy(s,"");
    mass1 = new double[N]; ///создаем двумерный массив
+
                cout << "Vvedite imya fila" << endl;
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
+
                cin >> s;
    {
+
                strcat(s, ".txt");
 
+
                ofstream outfile(s);
        Xi=i*__step+__start; ///расчитываем Хi
+
                outfile << "x          y" << endl;
        SumXY=SumXY+Xi*mass[i]; ///расчитываем SumXY
+
                for (int i = 0; i < f7.getlength(); i ++)
        SumX=SumX+Xi; ///расчитываем SumX
+
                    outfile << f7.getelx(i) << "          " << f7.getely(i) << endl;
        SumY=SumY+mass[i]; ///расчитываем SumY
 
        Sum_Xkv=Sum_Xkv+Xi*Xi; ///расчитываем Sum_Xkv
 
  
 +
                cout << "done" << endl;
 +
                cout << "Nazhmite \"b\" chotibi viti" << endl;
 +
                cin >> ce;
 +
                while (true)
 +
                if (ce == 'b')
 +
                    goto start;
 +
            }
 +
            case '8':
 +
                system("cls");
 +
                strcpy(s,"");
 +
                cout << "Vvedite imya fila" << endl;
 +
                cin >> s;
 +
                strcat(s, ".txt");
 +
                ofstream outfile(s);
 +
                outfile << "x          y" << endl;
 +
                for (int i = 0; i < f8.getlength(); i ++)
 +
                    outfile << f8.getelx(i) << "          " << f8.getely(i) << endl;
 +
                cout << "done" << endl;
 +
                cout << "Nazhmite \"b\" chotibi viti" << endl;
 +
                cin >> ce;
 +
                while (true)
 +
                if (ce == 'b')
 +
                    goto start;
 +
        }
 
     }
 
     }
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
</div>
  
    double a=(SumXY*N-SumX*SumY)/(N*Sum_Xkv-SumX*SumX); ///определяем тип и расчитываем коэффициент перед Х в уравнении аХ+b
+
'''[[Лобанов Илья]]'''
    double b=(SumY-a*SumX)/N; ///определяем тип и расчитываем свободный член в уравнении аХ+b
 
  
    if (b>0) ///если b положительное то
+
'''Описание программы''':
    cout<<"Апроксимация: "<<a<<"*x+"<<b<<endl; ///выводим на экран: Апроксимация: а*Х+b
+
Программа позволяет складывать , вычитать , делить,умножать 2 функции,заданные на одном интервале.При считывании с файла сначала указывается отрезок, потом величина шага, а потом дискретные значения.
  
    else if (b<0) ///если b отрицательно то
+
Скачать можно [[http://tm.spbstu.ru/File:func.rar тут]]
    cout<<"Апроксимация: "<<a<<"*x"<<b<<endl; ///выводим на экран: Апроксимация: а*Х b
 
  
    for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
 
    {
 
        mass1[i] = a*(i*__step+__start)+b; ///при помощи массива создаем функцию подсчета точек при апроксимации
 
    }
 
  
    delete[] mass;
+
'''[[Лосева Татьяна]]'''
    mass=mass1;
+
    vivod();///вывод на экран
+
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.
    zapis("aprocsimation.txt");///сохраненяем в файл
 
  
}
+
'''Инструкция к программе:''' Начальная координата и шаг,для задания координат функций,передаются при вызове методов,создающих функции.Начальный шаг,шаг интерполяции,а так же количество выводимых координат заданы глобально.Поэтому просто запускайте программу, при желании поменяйте заданные
 +
величины.
  
functya operator+ ( functya F) ///перегрузка оператора +
+
Cкачать программу можно  [http://tm.spbstu.ru/Файл:Loseva.rar здесь]
{
 
  
    functya tmp(start,ending,step);
+
<div class="mw-collapsible-content">
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream>
  
    mass2=new double[amount];///создаем двумерный массив
+
using namespace std;
    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;
 
  
}
+
#define N 5//количество точек
  
functya operator-( functya F)///перегрузка оператора -
+
const double l1 = 5;//задаём начальный шаг функций
{
+
const double l2 = 0.7;//шаг для интерполяции
  
    functya tmp(start,ending,step);
+
class Func
 +
{//класс,хранящий функцию,содержащий методы:печать,перегрузка,интерполяция,апроксимация
  
    mass2=new double[amount];///создаем двумерный массив
+
public:
    for (int i=0; i<amount; i++)
+
Func(int size) : size_(size), ax(new double[size]), by(new double[size])//создаём два массива,заполняем нулями
    {
+
{
        mass2[i]=mass[i] - F.mass[i];///находим разность двух функций
+
for (int i = 0; i< size_; i++)
    }
+
{
 
+
ax[i] = 0;
    delete [] mass;
+
by[i] = 0;   //все элементы обоих массивов обнуляются
    mass=mass2;
+
}
    vivod();///выводим на экран результат
+
}
    zapis("f3.txt");///сохраненяем в файл
 
    cout<<"Введите шаг для интерполяции";
 
    cin>>step2;
 
    cout<<"Интерполяция: "<<"\n";
 
    interpol(start,ending,step2);///вызов функции интерполяции
 
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 
    return tmp;
 
  
}
+
void print()//вывод на экран
 +
{
 +
cout << "x: ";
 +
for (int i = 0; i < size_; i++)
 +
cout << ax[i] << " ";
 +
cout << endl << "y: ";
 +
for (int i = 0; i < size_; i++)
 +
cout << by[i] << " ";
 +
cout << endl;
 +
}
  
functya operator*( functya F)///перегрузка оператора *
+
Func &operator+(Func &f2)//функция перегрузки:cложение функций
{
+
{
    functya tmp(start,ending,step);
+
Func *result = new Func(size_);//создаём результирующую функцию,равную сумме двух f2 и this
 +
for (int i = 0; i < size_; i++)
 +
{
 +
result->ax[i] = this->ax[i];//суммируем координаты X
 +
result->by[i] = f2.by[i] + this->by[i];//суммируем координаты Y
 +
}
 +
cout << "Sum f(x)=f1+f2:" << endl;//выводим на экран сумму функций
 +
result->print();
 +
return *result;
 +
}
  
    mass2=new double[amount];///создаем двумерный массив
+
void Int(double L) //метод Интерполяции
    for (int i=0; i<amount; i++)
+
{
    {
+
int M = (this->ax[this->size_ - 1] - this->ax[0]) / L + 1; //M- количество элементов массива с координатами интерполирующей функции;
        mass2[i]=mass[i] * F.mass[i];///находим произведение двух функций
+
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;//считаем номер элемента,"левого" от искомого
  
    delete [] mass;
+
                      //интерполируем Y по формуле
    mass=mass2;
+
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]);
    vivod();///выводим на экран результат
 
    zapis("f3.txt");///сохраненяем в файл
 
    cout<<"Введите шаг для интерполяции";
 
    cin>>step2;
 
    cout<<"Интерполяция: "<<"\n";
 
    interpol(start,ending,step2);///вызов функции интерполяции
 
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 
    return tmp;
 
  
}
+
}
  
functya operator/( functya F)///перегрузка оператора /
+
result.print();//выводим результат
{
+
}
  
    functya tmp(start,ending,step);
+
void aprox()//Апроксимация
 +
{
 +
double a=0;
 +
          for(int i=0;i<size_;i++)//считаем сумму x
 +
  a=this->ax[i]+a;
 +
       
  
    mass2=new double[amount];///создаем двумерный массив
+
double b=0;
    for (int i=0; i<amount; i++)
+
for(int i=0;i<size_;i++)//считаем сумму y
    {
+
b=this->by[i]+b;
        mass2[i]=mass[i] / F.mass[i];///находим частное двух функций
+
    }
 
  
    delete [] mass;
+
double c=0;
    mass=mass2;
+
for(int i=0;i<size_;i++)//считаем сумму квадратов x
    vivod();///выводим на экран результат
+
c=(this->ax[i])*(this->ax[i])+c;
    zapis("f3.txt");///сохраненяем в файл
+
    cout<<"Введите шаг для интерполяции ";
 
    cin>>step2;
 
    cout<<"Интерполяция: "<<"\n";
 
    interpol(start,ending,step2);///интерполяция
 
    aprocsimation(start,ending,step2);///вызов функции аппроксимации
 
    return tmp;
 
  
}
+
double d=0;
 +
for(int i=0;i<size_;i++)//считаем сумму xy
 +
d=(this->ax[i])*(this->by[i])+d;
 +
  
void vivod ()///создаем функцию вывода на экран
+
//затем решаем систему для у=kx+m
{
+
//(1)c*k+a*m=d
 +
//(2)a*k+size_*m=b;
 +
//k=(d-am)/с
 +
//подставим в (2)
 +
double m;
 +
m=(b*c-a*d)/(c*size_-a*a);
 +
double k;
 +
k=(d-a*m)/c;
 +
cout<<"aproximacia :: ";
 +
cout<<"y="<<k<<"x+"<<m<<endl;
  
    for (int l=0; l<amount; l++)
+
}
    {
 
        cout<<"Х"<<l<<setw(10)<< "Y= " << mass[l] <<"\n";
 
    }
 
  
}
 
  
void zapis (char Zapis[])///созданем функцию записи в файл
+
double *ax;
{
+
double *by;
  
    ofstream fout(Zapis);
+
private:
    for (int l=0; l<amount; l++)
+
int size_;//размер массива
    {
+
};
        fout<<"X="<<l<<setw(10)<<"Y="<<mass[l]<<" \n";
 
    }
 
  
    fout.close();
 
  
}
 
  
};
 
  
int main()
+
class Cord//класс,создающий и хранящий значение функций
 
{
 
{
 +
public:
 +
Cord(double x0, double s) :x0(x0), s(s)//x0-начальная координата;s-шаг
 +
{
 +
}
  
    setlocale(LC_ALL,"RUS");
+
void Fyx1(Func func)//метод,считающий координаты нашей функции y=x
 
+
{
    double start1, ending1, step1, step2;
+
int i;
    int number;
+
func.ax[0] = x0;
    cout<< "Введите начало отрезка ";
+
for (i = 1; i < N; i++)//считаются иксы
    cin>> start1;
+
{
    cout<< "Введите конец отрезка ";
+
func.ax[i] = x0 + s;
    cin>> ending1;
+
x0 = func.ax[i];
    cout<<"Введите шаг для функций ";
+
}
    cin>> step1;
+
for (i = 0; i<N; i++)
 +
func.by[i] = func.ax[i];//считаем координаты у
 +
cout << "f1 :" << endl;
 +
func.print();
 +
cout << endl;
 +
}
  
    functya F1(start1,ending1,step1);///создаем первую функцию
+
void Fyx2(Func func)//метод,считающий координаты нашей функции y=x+1
    F1.massiv1();
+
{
    F1.vivod();///выводим координаты первой функции на экран
+
int i;
    F1.zapis("F1.txt");///записываем координаты первой функции в файл
+
func.ax[0] = x0;
 +
for (i = 1; i<N; i++)//считаем иксы
 +
{
 +
func.ax[i] = x0 + s;
 +
x0 = func.ax[i];
 +
}
 +
for (i = 0; i<N; i++)
 +
func.by[i] = func.ax[i] + 1;//считаем игрики
 +
cout << "f2 :" << endl;
 +
func.print();
 +
cout << endl;
 +
}
  
    cout<<"\n \n";
+
private:
 +
double x0;//начальная координата
 +
double s;//шаг
 +
};
  
    functya F2(start1,ending1,step1);///создаем вторую функцию
+
int main()
    F2.massiv2();
+
{
    F2.vivod();///выводим координаты второй функции на экран
+
Func f1(N);//создание функции f1
    F2.zapis("F2.txt");///записываем координаты второй функции в файл
+
Func f2(N);//создание f2
 +
Cord s1(0, l1);//cоздаём объект s1
 +
Cord s2(0, l1);//cоздаём объект s2
 +
s1.Fyx1(f1);//задаём координаты 1ой функции
 +
s2.Fyx2(f2);//задаём координаты 2ой функции
 +
 
 +
      //сложение функций:
 +
 +
Func f3 = f2 + f1;//есть тоже ,что и Func f3 = f2.operator+(f1);
  
    cout<<"\n \n";
+
f1.Int(l2);//Интерполируем f1 с новым шагом l2
 +
f1.aprox();//Апроксимируем f1
 +
 +
getchar();
 +
return 0;
 +
}
  
    functya F3(start1, ending1, step1);
+
</syntaxhighlight>
 +
</div>
  
    cout<<"Выберите, что вы хотите сделать с функциями: 1-найти сумму, 2-найти разность, 3-найти произведение, 4-найти частное ";
+
'''[[Сергей Ляжков]]'''
    cin>>number;
+
'''Описание программы''':программа позволяет проводить следующие действия с функциями: сложение, вычитание, умножение, те же действия с числами, проводить аппроксимацию и интерполяцию
    cout<<"\n \n";
+
Скачать можно [[http://tm.spbstu.ru/File:Функции.zip тут]]
  
    if(number==1)
+
<br>'''[[Нарядчиков Александр]]'''<br>
    {
+
'''Инструкция:''' Пользователю достаточно просто запустить программу.<br>
        F3=F1+F2;
+
'''Описание программы:''' В окне рисуются графики с разным шагом, количеством точек, начальными и конечными координатами, по клавише '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
 +
*/
  
    else if (number==2)
+
#include "GRAPH.H"
    {
 
        F3=F1-F2;
 
    }
 
  
    else if (number==3)
+
/* Глобальные переменные */
    {
+
// Глобальная переменная, хранящая время в секундах с момента старта программы
        F3=F1*(F2);
+
double SyncTime;
    }
+
// Глобальные переменные для отслеживания нажатия клавиш
 +
bool IsGraph, IsSave, IsLoad, IsLoaded;
  
    else if (number==4)
+
/* Timer function */
    {
+
// Подсчет времени
        F3=F1/F2;
+
void Timer( void )
    }
+
{
 +
long t;
 +
static long StartTime = -1;
  
    else
+
t = clock();
    {
+
if (StartTime == -1)
        cout<<"Ошибка ";
+
StartTime = t;
    }
+
SyncTime = (double)(t - StartTime) / CLOCKS_PER_SEC;
 +
} /* End of 'Timer' function */
  
    return 0;
+
/* Display function */
 +
// Стандартная функция, вызываемая при перерисовке окна
 +
void Display( void )
 +
{
 +
graph G1(-15, 15, 0.1), G2(2, 10, 0.4), G3, G4;
  
}
+
// Запуск времени
</syntaxhighlight>
+
Timer();
</div>
 
  
 +
// Установка цвета закраски фона в белый
 +
glClearColor(1, 1, 1, 1);
 +
// Очищаем цветовой буфер для создания нового изображения
 +
glClear(GL_COLOR_BUFFER_BIT);
  
 +
glLoadIdentity();
 +
glScaled(0.1 / (1366 / 768.0), 0.1, 0.1);
  
'''[[Уманский Александр]]'''
+
// Отрисовка осей X и Y
 +
glBegin(GL_LINE_STRIP);
  
'''Инструкция к программе''': пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется.
+
glColor3d(0, 0, 1);
 +
glVertex2d(0, -1000);
 +
glVertex2d(0, 1000);
  
 +
glColor3d(1, 0, 0);
 +
glVertex2d(-1000, 0);
 +
glVertex2d(1000, 0);
  
 +
glEnd();
  
Скачать программу можно по [http://mech.spbstu.ru/File:Untitled1.rar ссылке]
+
/* Отрисовка графиков */
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
// Отрисовка первого графика и его интерполяция по клавише "G"
Метод наименьших квадратов
+
G1.Draw(sin);
задача состоит в том, чтобы минимизировать выражение:
+
if (IsGraph == 1)
1: http://mech.spbstu.ru/images/b/b0/003.png
+
G1.Interpolation_Draw(1.0 / 32);
Доказано, что минимум достигается при:
 
2: http://mech.spbstu.ru/images/2/20/005.png
 
записываем пункт 2 в нашу программу, находим коэффициенты и находим значение линейной функции y=ax+b, по интерполированным значениям x.
 
  
 +
// Отрисовка второго графика и его интерполяция по клавише "G"
 +
G2.Draw(log);
 +
if (IsGraph == 1)
 +
G2.Interpolation_Draw(1.0 / 32);
  
<div class="mw-collapsible-content">
+
// Отрисовка графика суммы для первого и второго графиков
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
G3 = G2 + G1;
 +
glColor3d(0, 1, 0);
 +
G3.Draw();
 +
// Аппроксимация графика суммы
 +
G3.Approximation();
  
#include <iostream>
+
// Сохранение графика по клавише "S"
#include <math.h>
+
if (IsSave == 1)
#include <iomanip>
+
{
#include<stdlib.h>
+
G3.SaveArray();
using namespace std;
+
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;
 +
}
  
class func
+
// Чистка памяти
{
+
delete[] G1.mas;
private:
+
delete[] G1.Color;
    double a/*начало*/,b/*конец*/,c/*шаг*/,k/**/,m/**/,rr/**/;
+
delete[] G2.mas;
    int d/*переменная для изменения типа, кол-во элементов для начальных элементов*/,tt/*переменная для изиенения типа, кол-ва элементов для счёта суммы*/;
+
delete[] G2.Color;
    double *F/*массив для значений У*/, *X/*Массив для значений Х*/, *R/*массив для значений У после интерполяции*/, *Q;
+
delete[] G3.mas;
public:
+
delete[] G3.Color;
 +
delete[] G4.mas;
 +
delete[] G4.Color;
  
    func (double a1, double b1, double c1):a(a1),b(b1),c(c1)//создаём конструктор для функции
+
glFinish();
    {
+
// Копируем вторичный буфер в окно
        double p = (b-a)/c;
+
glutSwapBuffers();
        d = (int)p;
+
// Вызываем функцию обновления кадра
        if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
+
glutPostRedisplay();
        else d += 1;
+
} /* End of 'Display' function */
  
        F = new double [d];//создание динамического массива для У
+
/* Keyboard function */
        X = new double [d];// создание динамического массива для Х
+
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
        X[0]=a;//первый элемент
+
void Keyboard( unsigned char Key, int X, int Y )
        X[d-1]=b;//последний элемент, для того чтобы последний элемент был в конце промежутка, чтобы его не потерять
+
{
        for(int i = 1; i < d-1; i++) X[i]=a+c*i; //присваивание значений всех Х
+
// Выход из программы
 +
if (Key == 27)
 +
exit(0);
 +
// Отрисовка интерполированных графиков
 +
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 */
    void first ()//функция для первой функции
+
int main( int argc, char *argv[] )
    {
+
{
        double y;//в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
+
// Инициализации OpenGL и GLUT
        F[0]=pow(2,a);//объявление значения У для начала промежутка
+
glutInit(&argc, argv);
        F[d-1]=pow(2,b);//объявление значения У для конца промежутка
+
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
        for(int i = 1; i < d-1; ++i)
 
        {
 
            y = pow(2,((c*i)+a));//высчитываем значения У внутри промежутка
 
            F[i] = y;//присваиваем массиву значения по У
 
        }
 
  
        cout << " " << endl;//пробел и конец строки
+
// Задача размеров и позиции окна
    }
+
glutInitWindowPosition(0, 0);
 +
glutInitWindowSize(500, 500);
 +
// Создание окна
 +
glutCreateWindow("T05GRAPH");
  
    void second ()//функция для второй функции
+
// Установка функций 'обратного вызова'
    {
+
glutDisplayFunc(Display);
        if(a==0 || b==0) return;
+
glutKeyboardFunc(Keyboard);
        F[0]=1*a*a; //присваивание значения функции в начале промежутка
 
        F[d-1]=1*b*b;//присваивание значения функции в конце промежутка
 
  
        for(int k = 1; k <d-1; ++k)
+
// Запускаем основной цикл построения
        {
+
glutMainLoop();
            double n = c*k+a;
+
return 0;
            if (n != 0)//условие неделимости на ноль
+
} /* End of 'main' function */
            {
 
                F[k] = 1*n*n;
 
            }
 
        }
 
  
    }
+
/* END OF 'T05GRAPH.CPP' FILE */
 +
</syntaxhighlight>
 +
"'''GRAPH.CPP'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: GRAPH.CPP
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
    void operator +(func Q)//перегрузка оператора +
+
#include "GRAPH.H"
    {
 
        sum(Q);
 
    }
 
  
    void sum (func Q)//функция суммирования функций на интерполированном шаге
+
/* Load Array of points function */
    {  double m, p = (b-a)/c;
+
// Загрузка графика из файла по точкам
    int i;
+
void graph::LoadArray( char *FileName )
        R=new double[d+2];
+
{
          if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
+
// Создание указателя на тип FILE
        else d += 1;
+
FILE *F;
    m=a;
 
cerr<<"\n";
 
  
        for(i = 0; i <d-1; ++i)//цикл суммирования функций и вывода значений суммы, функций и иксов
+
// Создание файла и открытие его в режиме чтения
        {
+
fopen_s(&F, FileName, "rt");
  
            cerr <<"YFirst: "<< F[i] << "   ";
+
// Количество точек
            cerr << "YSecond: "<< Q.F[i] << "   ";
+
fscanf(F, "%d", &N);
            R[i] = F[i] + Q.F[i];
+
// Шаг функции
            cerr << "Ysum: "<< R[i] << "  ";
+
fscanf(F, "%lf", &Step);
            cerr << "X:" << m << '\n';
+
// Начальная координата по X
 +
fscanf(F, "%lf", &MinX);
 +
// Конечная координата по X
 +
fscanf(F, "%lf", &MaxX);
 +
 +
// Выделение памяти под массив точек
 +
mas = new vec[N];
  
            m=m+c;
+
// Заполнение массива точек из файла
        }
+
for (int i = 0; i < N; ++i)
  for(i = 0; i <d-1; ++i)
+
{
        {Q.F[i]=R[i];
+
// Заполнение по X
}
+
fscanf(F, "%lf", &mas[i].X);
        cerr << " " << endl;
+
// Заполнение по Y
    }
+
fscanf(F, "%lf", &mas[i].Y);
 +
}
  
double interp( double pnt/*новый шаг*/, func Q)//функция для интерполяции функции
+
// Закрытие файла
    {double p,h,i,w,*X,aApr,bApr,X2sm,XYsm,Xsm/*хранит сумму интерполированных иксов*/,Ysm/*хранит сумму интерполированных игреков*/;
+
fclose(F);
    int q,k,l,o;
+
} /* End of 'LoadArray' function */
    p=(b-a)/pnt+1;
 
    q=int(p);
 
    R=new double [q];
 
    X=new double [q];
 
  
    l=0;
+
/* Fill mas function */
    k=0;
+
// Заполнение массива координат точек с цветом
 +
void graph::Fill( double(*f)(double) )
 +
{
 +
// Выделение памяти под массив точек
 +
mas = new vec[N];
 +
// Выделение памяти под массив цветов
 +
Color = new vec[N];
  
    for(h=a/*начало функции*/; h<=b/*конец функции*/; h=h+c/*старый шаг*/) //шагает по нормальному шагу
+
// Заполнение массивов
    {
+
for (int i = 0; i < N; i++)
        for(i=a-1; i<=b; i=i+pnt/*новый шаг*/)
+
{
          if((i>h)&&(i<=(h+c)))//проверяет лежит ли новый шаг между точками старого
+
mas[i] = vec(MinX + i * Step, f(MinX + i * Step));
            {   R[k]=(Q.F[l]-Q.F[l-1])*(i-h)/c+Q.F[l-1];//формула интерполяции
+
Color[i] = vec::Rnd();
                cout<<"\n"<<"Yinter: "<<R[k]<<"  "<<"X: "<<i-1;//вывод интерполированных значений и иксов
+
}
                X[k]=i-1;
+
} /* End of 'Fill' function */
                k++;
 
            }
 
        l++;
 
    }
 
    cout<<"\n";
 
    cout<<"\n";
 
    cout<<"\n";
 
    //обнуление значений сумм для МНК
 
    Xsm=0;
 
    Ysm=0;
 
    XYsm=0;
 
    X2sm=0;
 
  
    for(o=0;o<=k;o++)//цикл подготавливает суммы для МНК
+
/* Draw graph function */
        {Xsm+=X[o];
+
// Рисование заполненного графика на экран
        Ysm+=R[o];
+
void graph::Draw( void )
        XYsm+=X[o]*R[o];
+
{
        X2sm+=X[o]*X[o];
+
  // Задача размер точки
        }
+
glPointSize(1);
 
+
// Рисование
aApr=(k*XYsm-Xsm*Ysm)/(k*X2sm-Xsm*Xsm);//находим коэфициенты по МНК
+
glBegin(GL_POINTS);
bApr=(Ysm-a*Xsm)/k;
+
for (int i = 0; i < N; i++)
cout<<"\n"<<"aAprox"<<a<<"  "<<"bAprox"<<b<<"\n";//выводим их
+
glVertex2d(mas[i].X, mas[i].Y);
for(o=0;o<k;o++)
+
glEnd();
        {c=aApr*X[o]+bApr;//считаем значение Y при данных коэфициентах
+
} /* End of 'Draw' function */
        cout<<"YAprox: "<<c<<" "<<"X:"<<X[o]<<"\n" ;
 
        }
 
  
 +
/* Draw graph function */
 +
// Рисование не заполненного еще графика на экран
 +
void graph::Draw( double(*f)(double) )
 +
{
 +
// Заполнение массива
 +
graph::Fill(f);
  
    return 0;}
+
// Задача цвета и размера точки
};
+
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 */
  
int main(){
+
/* Interpolation draw graph function */
    double x, xn, s1,pnt;
+
// Рисование интерполированного графика на экран
    cout << "Input the beginning of the function: " << endl;
+
void graph::Interpolation_Draw( double i_step )
    cin >> x;
+
{
    cout << "Input the ending of the function: " << endl;
+
// Коэффициент Катмулл-Рома
    cin >> xn;
+
double alpha = 1.0 / 6;
    cout << "Input step for the function: " << endl;
+
    cin >> s1;
+
// Кубическая интерполяция кривыми Безье
    func H(x,xn,s1);
+
for (int i = 0; i < N - 1; i++)
    H.first();
+
{
    func G(x,xn,s1);
+
// Создание 4 точек для интерполяции по ним
    G.second();
+
vec P0 = mas[i], P1, P2, P3 = mas[i + 1];
    H+G;
+
vec Color0 = mas[i], Color1, Color2, Color3 = mas[i + 1];
    cout<<"\n" << "Input new step for the function: " << endl;
 
    cin >> pnt;
 
    H.interp(pnt,G);
 
  
return 0;}
+
// Значения для первого и последнего отрезков
</syntaxhighlight>
+
if (i == 0)
</div>
+
{
 +
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);
 +
glBegin(GL_LINE_STRIP);
 +
for (double t = 0; t <= 1; t += i_step)
 +
{
 +
vec p, color;
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
// Вычисление точки интерполированного графика по 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 */
1. Пользователь вводит параметры первой функции
+
// Интерполяция графика
2. Пользователь вводит параметры второй функции (при этом шаг второй функции меньше шага первой)
+
graph graph::Interpolation( double i_step )
3. Происходит интерполяция первой функции по второй
+
{
4. Пользователь выбирает арифметическую операцию
+
graph G_New;
5. При желании пользователь может выполнить аппроксимацию полученного результата
+
// Коэффициент Катмулл-Рома
 +
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;
 +
}
 +
}
  
Скачать можно [http://tm.spbstu.ru/File:Funcc.rar тут].
+
return G_New;
 
+
} /* End of 'Interpolation' function */
 
 
<div class="mw-collapsible-content">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#ifndef FUNC_H
 
#define FUNC_H
 
 
 
  
class Func
+
/* Sum of 2 graphics function */
 +
// Сложение двух графиков
 +
graph graph::operator+( graph &G )
 
{
 
{
    public:
+
graph G_New, G1, G2;
        Func(double a1, double b1, double c1);
+
int i, j;
        virtual ~Func();
+
 
        void DefFunc ();    // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
+
// Заполнение параметров графика суммы
        void PluFunc (Func D); // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
+
G_New.MinX = (MinX >= G.MinX) ? MinX : G.MinX;
        void operator +(Func D); // перегрузка оператора '+'
+
G_New.MaxX = (MaxX <= G.MaxX) ? MaxX : G.MaxX;
        void MinFunc (Func D);  // функция, линейно вычитающая значения второй функции из значений первой функции
+
G_New.Step = Step * G.Step;
        void operator -(Func D); // перегрузка оператора '-'
+
G_New.N = (int)((G_New.MaxX - G_New.MinX) / G_New.Step);
        void UmnFunc (Func D); // функция, линейно переумножающая значения функций
+
G_New.mas = new vec[G_New.N];
        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
+
// Интерполяция слагаемых графиков, для приведение к общему шагу
 +
G1 = Interpolation(G.Step);
 +
G2 = G.Interpolation(Step);
  
 +
// Поиск общего начала и конца графиков
 +
for (i = 0; i < G1.N; i++)
 +
if (fabs(G1.mas[i].X - G_New.MinX) <= Threshold)
 +
break;
  
 +
for (j = 0; j < G2.N; j++)
 +
if (fabs(G2.mas[j].X - G_New.MinX) <= Threshold)
 +
break;
  
#include "Func.h"
+
// Заполнение графика суммы
#include <fstream>
+
for (int k = 0; k < G_New.N; k++)
#include <iostream>
+
{
#include <math.h>
+
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;
 +
}
  
Func::Func(double a1, double b1, double c1):a(a1),b(b1),c(c1)  // конструктор для класса Func, создающий объект данного класса, определенный тремя значениями, введенными пользователем
+
return G_New;
{
+
} /* End of 'Sum' function */
    double d=(b-a)/c;   // расчет количества элементов, определяющих функцию
 
    j=floor(d);    // созданной целочисленной переменной присваивается значение, равное целой части числа, рассчитанного выше, с округлением в меньшую сторону
 
    A = new double [j+1];  // создание массива
 
}
 
  
Func::~Func()   // деструктор для класса Func
+
/* Save Array of points function */
 +
// Сохранение графика в файл по точкам
 +
void graph::SaveArray( void )
 
{
 
{
    //dtor
+
// Создание указателя на тип FILE
}
+
FILE *F;
  
void Func::Viv ()  // Функция вывода на экран значений
+
// Создание файла и открытие его в режиме записи
{
+
fopen_s(&F, "graph.txt", "wt");
    std::cout << "x ";
 
    for (int z=0; z<=j; ++z)
 
    {
 
        std::cout << z+1 << " ";
 
    }
 
}
 
  
void Func::DefFunc ()   // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
+
/* Запись в файл данных */
{
+
// Количество точек
    double x;   // создание переменной, используемой для расчета значений функции
+
fprintf(F, "%d\n", N);
    for(int i=0; i<=j; ++i) // создание цикла, рассчитывающего j элементов
+
// Шаг функции
    {
+
fprintf(F, "%lf\n", Step);
        x =i*c+a;  // задание значения перемнной x, определенной выше
+
// Начальная координата по X
        A[i]=x*x;  // задание значения самой функции (при этом в данной ситуации нам неважно, как именно задается функция, ее значения могут быть определены любым способом, от этого алгоритм не меняется)
+
fprintf(F, "%lf\n", MinX);
        std::cerr << A[i] << " ";   // вывод на экран значения функции
+
// Конечная координата по X
    }
+
fprintf(F, "%lf\n", MaxX);
}
+
 
 +
// Координаты всех точек
 +
for (int i = 0; i < N; ++i)
 +
  fprintf(F, "%lf %lf ", mas[i].X, mas[i].Y);
 +
 
 +
// Закрытие файла
 +
fclose(F);
 +
} /* End of 'SaveArray' function */
  
void Func::PluFunc (Func D)  // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
+
/* Approximation of function function */
 +
// Аппроксимация графика
 +
void graph::Approximation( void )
 
{
 
{
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
double k, b, s1 = 0, s2 = 0, s3 = 0, s4 = 0;
    for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
+
 
    {
+
// Линейная аппроксимация
        B[i]=B[i]+D.A[i];   // сложение значений двух функций для одного и того же значения переменной
+
for (int i = 0; i < N; i++)
    }
+
{
    for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
if (fabs(mas[i].X) < MAX && fabs(mas[i].Y) < MAX)
    {
+
{
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
+
s1 += mas[i].X * mas[i].Y;
    }
+
s2 += mas[i].X;
    out.close();   // закрытие файла после записи в него значений
+
s3 += mas[i].X * mas[i].X;
    D.Viv();
+
s4 += mas[i].Y;
    std::cout << std::endl << "y ";
+
}
    for (int i=0; i<=D.j; ++i)  // аналогичный предыдущему цикл, выводящий значения на экран
+
}
    {
+
 
        std::cout << B[i] << " ";
+
k = (N * s1 - s2 * s4) / (double(N) * s3 - s2 * s2);
    }
+
b = (s4 - k * s2) / double(N);
}
+
 
void Func::operator +(Func D)   // перегрузка оператора '+'
+
// Задача цвета и ширины линии
{
+
glColor3d(1, 0.5, 0);
    PluFunc(D);                         // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1+f2 будет работать аналогично записи f1.PluFunc(f2)
+
glLineWidth(1);
}
+
// Рисование
void Func::MinFunc (Func D)   // функция, линейно вычитающая значения второй функции из значений первой функции
+
glBegin(GL_LINE_STRIP);
{
+
glVertex2d(MinX, MinX * k + b);
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
glVertex2d(MaxX, MaxX * k + b);
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
+
glEnd();
    {
+
} /* End of 'Approximation' function */
        B[i]=B[i]-D.A[i];  // вычитание значений второй функций из значений первой для одного и того же значения переменной
+
 
    }
+
/* End of 'GRAPH.CPP' file */
    for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
</syntaxhighlight>
    {
+
"'''GRAPH.H'''"
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    }
+
/* FILENAME: GRAPH.H
    out.close();    // закрытие файла после записи в него значений
+
* LAST UPDATE: 17.01.2016
    D.Viv();
+
  */
    std::cout << std::endl << "y ";
+
 
    for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран
+
#ifndef _GRAPH_H_
    {
+
#define _GRAPH_H_
        std::cout << B[i] << " ";
+
 
    }
+
#define _CRT_SECURE_NO_WARNINGS
}
+
 
void Func::operator -(Func D)  // перегрузка оператора '-'
+
#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
 
{
 
{
    MinFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1-f2 будет работать аналогично записи f1.MinFunc(f2)
+
public:
}
+
double X, Y;
void Func::UmnFunc (Func D)    // функция, линейно переумножающая значения функций
+
 
{
+
/* Default constructor */
    std::ofstream out("zap.txt");    // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
vec( void )
    for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
+
{
    {
+
}
        B[i]=B[i]*D.A[i];  // умножение значений первой функций на значенийя второй для одного и того же значения переменной
+
 
    }
+
/* Class constructor */
    for (int i=0; i<=D.j; ++i)    // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
vec( double A ) : X(A), Y(A)
    {
+
{
        out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
+
}
    }
+
 
    out.close();    // закрытие файла после записи в него значений
+
/* Class constructor */
    D.Viv();
+
vec( double A, double B ) : X(A), Y(B)
    std::cout << std::endl << "y ";
+
{
    for (int i=0; i<=D.j; ++i)   // аналогичный предыдущему цикл, выводящий значения на экран
+
}
    {
+
 
        std::cout << B[i] << " ";
+
static double R0( void )
    }
+
{
}
+
return rand() / (double)RAND_MAX;
void Func::operator *(Func D)   // перегрузка оператора '*'
+
} /* End of 'R0' function */
{
+
 
    UmnFunc(D);    // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1*f2 будет работать аналогично записи f1.UmnFunc(f2)
+
static vec Rnd( void )
}
+
{
void Func::DelFunc (Func D)   // функция, линейно делящая значения первой функци на значения второй функции
+
return vec(R0(), R0());
{
+
} /* End of 'Rnd' function */
    std::ofstream out("zap.txt");  // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
+
 
    for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
+
/* The functions of operations on vectors */
    {
+
 
        B[i]=B[i]/D.A[i];       // деление значений первой функций на значенийя второй для одного и того же значения переменной
+
/* Vector = vector function */
    }
+
vec operator=( vec &B )
    for (int i=0; i<=D.j; ++i)      // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
{
    {
+
X = B.X;
        out << B[i] << '\n';        // запись значений, полученных в предыдущем цикле, в файл
+
Y = B.Y;
    }
+
 
    out.close();    // закрытие файла после записи в него значений
+
return B;
    D.Viv();
+
} /* end of 'operator+' function */
    std::cout << std::endl << "y ";
+
 
    for (int i=0; i<=D.j; ++i)      // аналогичный предыдущему цикл, выводящий значения на экран
+
/* Vector add vector function */
    {
+
vec operator+( const vec &B ) const
        std::cout << B[i] << " ";
+
{
    }
+
return vec(X + B.X, Y + B.Y);
}
+
} /* end of 'operator+' function */
void Func::operator /(Func D)  // перегрузка оператора '/'
+
 
{
+
/* Vector sub vector function */
    DelFunc(D);    // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1/f2 будет работать аналогично записи f1.DelFunc(f2)
+
vec operator-( const vec &B ) const
}
+
{
void Func::In (Func D)     // функция, интерполирующая первую функцию по второй
+
return vec(X - B.X, Y - B.Y);
{
+
} /* end of 'operator-' function */
    double l=c/D.c;    // создаем переменную, которой присваиваем значение, обозначающее, во сколько раз один шаг больше другого
+
 
    c=D.c;      // приводим больший шаг к меньшему значению
+
vec operator-( void ) const
    z=D.j+1;    // ранее созданной переменной присваиваем значение, равное количеству элементов плюс один
+
{
    int p=l;    // создаем целочисленную переменную, равную переменной l
+
return vec(-X, -Y);
    B = new double [D.j+2];    // создание массива с количеством элементов D.j+2
+
} /* end of 'operator-' function */
    D.Viv(); std::cout << std::endl << "y ";
+
 
    B[0]=A[0]; std::cerr << B[0] << " ";    // присваиваем первому элементу нового массива значение первого элемента старого массива и выводим его на экран
+
/* Vector mul number function */
    int k=0;    // создаем вспомогательную целочисленную переменную
+
vec operator*( const double N ) const
    for (int i=0; i<=j; i+=p)   // создаем цикл, рассчитанный на j повторов через p
+
{
    {
+
return vec(X * N, Y * N);
        for (int m=1; m<p; ++m)    // создание цикла, выссчитывавшего промежуточное значение
+
} /* end of 'operator*' function */
        {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)-ого элемента старого массива
+
/* Vector div number function */
        std::cerr << B[i+p] << " ";     // вывод высчитанного выше значения на экран
+
vec operator/( const double N ) const
        k=k+1; // увеличение k на единицу
+
{
    }
+
return vec(X / N, Y / N);
}
+
} /* end of 'operator/' function */
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();
 
}
 
  
 +
/* 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;
  
#include <iostream>
+
return *this;
#include <fstream>
+
} /* end of 'operator+=' function */
#include "Func.h"
 
  
using namespace std;
+
vec & operator-=( const vec &B )
double m,n,o, m1, n1, o1;
+
{
int a;
+
X -= B.X;
char b;
+
Y -= B.Y;
 +
 
 +
return *this;
 +
} /* end of 'operator-=' function */
 +
 
 +
vec & operator*=( const double N )
 +
{
 +
X *= N;
 +
Y *= N;
 +
 
 +
return *this;
 +
} /* end of 'operator*=' function */
 +
 
 +
vec & operator/=( const double N )
 +
{
 +
X /= N;
 +
Y /= N;
  
int main()
+
return *this;
{
+
} /* end of 'operator/=' function */
    cout << "Enter the beginning, the end and the step of a function." << endl; // ввод опорных значений первой функции: начало, конец, шаг;
 
    cin >> m >> n >> o; // считывание значений
 
    cout << "Enter the beginning, the end and the step of another function." << endl; // ввод опорных значений второй функции: начало, конец, шаг;
 
    cin >> m1 >> n1 >> o1; // считывание значений
 
    Func F(m,n,o); // создание объекта класса Func, определяющий первую функцию
 
    cout << "The first function is" << endl; F.Viv(); cout << endl << "y ";
 
    F.DefFunc(); // определение первой функции через создание массива с ее значениями
 
    cout << endl;
 
    Func F1(m1,n1,o1); // создание объекта класса Func, определяющий вторую функцию
 
    cout << "The second function is" << endl; F1.Viv(); cout << endl << "y ";
 
    F1.DefFunc(); // определение второй функции через создание массива с ее значениями
 
    cout << endl;
 
    cout << "As two functions have different steps, we made the interpolation of the first function." << endl;
 
    F.In(F1); // линейная интерполяция первой функции по второй
 
    cout << endl;
 
    cout << "What do you want to do with these functions?" << '\n' << "Enter 1 to sum them;" << '\n' << "Enter 2 to subtract the second from the first;" << '\n' << "Enter 3 to multiply them;" << '\n' << "Enter 4 to divide first by second" << endl;
 
    cin >> a;
 
    if (a==1)
 
    {cout << "Function 1 + function 2 =" << '\n'; F+F1;}  // сложение двух функций с одинаковым шагом и интервалом
 
    else if (a==2)
 
    {cout << "Function 1 - function 2 =" << '\n'; F-F1;}  // вычитание двух функций с одинаковым шагом и интервалом
 
    else if (a==3)
 
    {cout << "Function 1 * function 2 =" << '\n'; F*F1;}  // умножение двух функций с одинаковым шагом и интервалом
 
    else if (a==4)
 
    {cout << "Function 1 / function 2 =" << '\n'; F/F1;}  // деление двух функций с одинаковым шагом и интервалом
 
    cout << endl;
 
    cout << "Enter 5 to do the approximation of the result function" << endl;  // пользователь сам выбирает, выполнять ли аппроксимацию;
 
    cout << "Otherwise enter 6 to quit" << endl;
 
    cin >> a;
 
    if (a==5)
 
    {cout << "Appromaximation:" << endl;
 
    F.App();}  // аппроксимация
 
    return 0;
 
}
 
  
</syntaxhighlight>
+
double operator!( void ) const
</div>
+
{
 +
return double(X * X + Y * Y);
 +
} /* end of 'operator!' function */
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
/* Access vector components by index function */
'''[[Савельева Ольга]]'''
+
double operator[]( const int i ) const
+
{
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения.
+
switch (i)
<div class="mw-collapsible-content">
+
{
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
case 0:
#include <stdio.h>
+
return double(X);
#include <stdlib.h>
+
case 1:
//Бибилотека необходимая для возможности включения русского языка в консоли
+
return double(Y);
#include <locale.h>
+
}
 +
} /* end of 'operator[]' function */
 +
 
 +
/* Normalizing vector function */
 +
vec & Normalize( void )
 +
{
 +
double len = !*this;
 +
 
 +
if (len != 1 && len != 0)
 +
*this /= sqrt(len);
 +
return *this;
 +
} /* end of 'Normalize' function */
 +
}; /* end of 'vec' class */
  
class fun
+
/* Graph class */
 +
class graph
 
{
 
{
/*
 
fx - массив с дискретными значениями функции
 
a - начало отрезка определения функции
 
b - конец отрезка определения функции
 
dx - шаг
 
*/
 
double *fx, a, b, dx;
 
//Чтобы очусть ошибки округления в вещественных числах при сравнениях используется константа eps.
 
//К примеру два вещественных числа x и y сравниваются не так x>=y, а так x-y>=-eps.
 
const double eps = 1e-10; //1e-10 это тоже самое что 0.0000000001
 
 
 
public:
 
public:
//Коструктор по умолчанию
+
double MinX, MaxX, Step; // Начальная координата по X; Конечная координата по X; Шаг функции
fun();
+
int N; // Количество точек
//Конструктор копирования
+
vec *mas, *Color; // Массивы точек и цветов
fun(fun &tmp);
 
//Деструктор
 
~fun();
 
  
//Перегруженные операторы. Ключевое слово const в конце означает, что объект от которого вызвается метод не изменяется
+
/* Default constructor */
const fun operator+(const fun& right) const;
+
graph( void )
const fun operator-(const fun& right) const;
+
{
const fun operator*(const fun& right) const;
+
MinX = -10, MaxX = 10, Step = 0.1, N = 200;
const fun operator/(const fun& right) const;
+
}
const fun& operator=(const fun& right);
 
  
//Метод считывания из файла
+
/* Class constructor */
void readFile(const char *path);
+
graph( double _MinX, double _MaxX, double _Step ) : MinX(_MinX), MaxX(_MaxX), Step(_Step)
//Метод вывода в файл
+
{
void writeFile(const char *path);
+
N = (int)((MaxX - MinX) / Step);
 +
// Выделение памяти
 +
mas = new vec[N];
 +
Color = new vec[N];
 +
}
  
//Метод изменения шага
+
/* Load Array of points function */
void changeDx(double newDx);
+
void LoadArray( char *FileName );
//Метод вычисления значения в заданной точке
 
double getX(double x1);
 
};
 
  
//В конструкторе по умолчанию все просто.
+
/* Fill mas function */
fun::fun()
+
void Fill( double(*f)(double) );
{
 
a = b = dx = 0;
 
fx = NULL;
 
}
 
  
//Конструктор копирования
+
/* Draw graph function */
fun::fun(fun &tmp)
+
void Draw( double(*f)(double) );
{
 
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];
 
}
 
  
//Деструктор
+
/* Draw graph function */
fun::~fun()
+
void Draw( void );
{
 
//Освобождение памяти выделенной для массива дискретных значений
 
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];
 
  
//Возвращение результата
+
/* Interpolation draw graph function */
return result;
+
void Interpolation_Draw( double i_step );
}
 
  
//Этот оператор аналогичен оператору сложение
+
/* Interpolation graph function */
const fun fun::operator-(const fun& right) const
+
graph Interpolation( double i_step );
{
 
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;
+
/* Sum of 2 graphics function */
}
+
graph operator+( graph &G );
  
//Этот оператор аналогичен оператору сложение
+
/* Save Array of points function */
const fun fun::operator*(const fun& right) const
+
void SaveArray( void );
{
 
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;
+
/* Approximation of function function */
}
+
void Approximation( void );
 +
}; /* end of 'graph' class */
  
//Этот оператор аналогичен оператору сложение
+
#endif /* _GRAPH_H_ */
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;
+
/* End of 'GRAPH.H' file */
}
+
</syntaxhighlight>
 +
</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)
+
'''[[Рубинова Раиса]]'''
{
 
//Проверка на самоприсваивание
 
if (this == &right)
 
//Возвращение в качестве результата текущий объект
 
return *this;
 
  
 +
'''Описание программы''': программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции.
  
int i, n;
+
'''Инструкция к программе''':
//Присваивание свойств объекта right текущему объекту
+
1. Пользователь вводит параметры первой функции
a = right.a;
+
2. Пользователь вводит параметры второй функции (при этом шаг второй функции меньше шага первой)
b = right.b;
+
3. Происходит интерполяция первой функции по второй
dx = right.dx;
+
4. Пользователь выбирает арифметическую операцию
//Вычисление количества дискретных значений
+
5. При желании пользователь может выполнить аппроксимацию полученного результата
n = (b - a) / dx + 1;
+
 
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
+
 
if (fx != NULL) delete[] fx;
+
Скачать можно [http://tm.spbstu.ru/File:Funcc.rar тут].
//Выделение необходимой памяти для хранения дискретных значений
 
fx = new double[n];
 
  
//Копирование дискретных значений объекта right в текущий объект
 
for (i = 0; i<n; ++i)
 
fx[i] = right.fx[i];
 
  
//Возвращение в качестве результата текущий объект
+
<div class="mw-collapsible-content">
return *this;
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
}
+
#ifndef FUNC_H
 +
#define FUNC_H
  
/*
 
Метод считывания из файла
 
path - путь к файлу из которого считывать
 
*/
 
  
void fun::readFile(const char *path)
+
class Func
 
{
 
{
//Открытие файла для считывания
+
    public:
FILE *in = fopen(path, "r");
+
        Func(double a1, double b1, double c1);
int i, n;
+
        virtual ~Func();
//Считывание границ отрезка и шага из файла
+
        void DefFunc ();    // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
fscanf(in, "%lf%lf%lf", &a, &b, &dx);
+
        void PluFunc (Func D); // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
//Вычисление количества дискретных значений
+
        void operator +(Func D); // перегрузка оператора '+'
n = (b - a) / dx + 1;
+
        void MinFunc (Func D); // функция, линейно вычитающая значения второй функции из значений первой функции
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
+
        void operator -(Func D); // перегрузка оператора '-'
if (fx != NULL) delete[] fx;
+
        void UmnFunc (Func D);  // функция, линейно переумножающая значения функций
//Выделение необходимой памяти для хранения дискретных значений
+
        void operator *(Func D); // перегрузка оператора '*'
fx = new double[n];
+
        void DelFunc (Func D);  // функция, линейно делящая значения первой функци на значения второй функции
//Считывание дискретных значений из файла
+
        void operator /(Func D); // перегрузка оператора '/'
for (i = 0; i<n; ++i) fscanf(in, "%lf", &fx[i]);
+
        void In (Func D);   // функция, интерполирующая первую функцию по второй
//Закрытие файла
+
        void App (); // функция, аппроксимирующая полученную в результате сложения/вычитания/деления/умножения двух функций функцию
fclose(in);
+
        void Viv ();  // Функция вывода на экран значений
}
+
    protected:
 +
    private:
 +
        double a,b,c;
 +
        int j,z;
 +
        double *A,*B;
 +
};
 +
 
 +
#endif // FUNC_H
 +
 
 +
 
  
/*
+
#include "Func.h"
Метод вывода в файл
+
#include <fstream>
path - путь к файлу в который нужно вывести
+
#include <iostream>
*/
+
#include <math.h>
  
void fun::writeFile(const char *path)
+
Func::Func(double a1, double b1, double c1):a(a1),b(b1),c(c1)  // конструктор для класса Func, создающий объект данного класса, определенный тремя значениями, введенными пользователем
 
{
 
{
//Открытие файла для вывода
+
    double d=(b-a)/c;  // расчет количества элементов, определяющих функцию
FILE *out = fopen(path, "w");
+
    j=floor(d);   // созданной целочисленной переменной присваивается значение, равное целой части числа, рассчитанного выше, с округлением в меньшую сторону
int i, n;
+
    A = new double [j+1];   // создание массива
double x = a;
+
}
//Вычисление количества дискретных значений
+
 
n = (b - a) / dx + 1;
+
Func::~Func()   // деструктор для класса Func
//Вывод информации о отрезке и шаге в файл
+
{
fprintf(out, "[%.5lf, %.5lf] dx=%.5lf\n", a, b, dx);
+
    //dtor
//Последовательный вывод пары (точка, значение в точке) в файл
+
}
for (i = 0; i<n; ++i, x += dx)
+
 
fprintf(out, "x=%.5lf f(x)=%.5lf\n", x, fx[i]);
+
void Func::Viv ()  // Функция вывода на экран значений
//Закрытие файла
+
{
fclose(out);
+
    std::cout << "x ";
 +
    for (int z=0; z<=j; ++z)
 +
    {
 +
        std::cout << z+1 << " ";
 +
    }
 
}
 
}
  
/*
+
void Func::DefFunc ()   // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
Метод изменения величины шага
 
*/
 
void fun::changeDx(double newDx)
 
 
{
 
{
int i, j, n, newN;
+
    double x;   // создание переменной, используемой для расчета значений функции
double *newFx, x, newX, x1, y1, x2, y2, K, B;
+
    for(int i=0; i<=j; ++i) // создание цикла, рассчитывающего j элементов
//Вычисление количества старых дискретных значений
+
    {
n = (b - a) / dx + 1;
+
        x =i*c+a;   // задание значения перемнной x, определенной выше
//Вычисление количества новых дискретных значений
+
        A[i]=x*x;   // задание значения самой функции (при этом в данной ситуации нам неважно, как именно задается функция, ее значения могут быть определены любым способом, от этого алгоритм не меняется)
newN = (b - a) / newDx + 1;
+
        std::cerr << A[i] << " ";   // вывод на экран значения функции
//Выделение памяти под новые дискретные значения
+
    }
newFx = new double[newN];
 
//Определение первой точки в которой вычисляется новое дискретное значение
 
newX = a;
 
//Переменная которая бежит по старым дискретным значениям
 
i = 0;
 
//Определение первой точки в которой вычисляется старое дискретное значение
 
x = a;
 
//Цикл для формирования новых дискретных значений
 
for (j = 0; j<newN; ++j, newX += newDx)
 
{
 
//В цикле находим отрезок где лежит точка в которой нужно вычислить новое дискретное значение
 
for (; i<n - 1; ++i, x += dx)
 
//Если без eps, то сравнения такие: x<=newX<=x+dx
 
if ((newX - x>-eps) && ((x+dx) - newX>-eps))
 
{
 
//Линейная интерполяция
 
x1 = x;
 
x2 = x + dx;
 
y1 = fx[i];
 
y2 = fx[i + 1];
 
K = (y2 - y1) / (x2 - x1);
 
B = (y2*x1 - y1*x2) / (x1 - x2);
 
//Вычисления значения в точке с помощью линейной интерполяции
 
newFx[j] = newX*K + B;
 
//Выход из цикла по i
 
break;
 
}
 
}
 
//Смена величины шага на новый
 
dx = newDx;
 
//Удаление старых дискретных значений
 
delete[] fx;
 
//Присвоение текущему объекту новых дискретных значений
 
fx = newFx;
 
 
}
 
}
  
/*
+
void Func::PluFunc (Func D)  // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
Метод вычисляет значение в точке xAns с помощью линейной интерполяции.
 
*/
 
double fun::getX(double xAns)
 
 
{
 
{
int i, n;
+
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
double x, x1, y1, x2, y2, K, B;
+
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
x = a;
+
    {
//Вычисление количества дискретных значений
+
        B[i]=B[i]+D.A[i];  // сложение значений двух функций для одного и того же значения переменной
n = (b - a) / dx + 1;
+
    }
//Ищем отрезок в котором лежит точка xAns
+
    for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
for (i = 0; i<n - 1; ++i, x += dx)
+
    {
{
+
        out << B[i] << '\n';   // запись значений, полученных в предыдущем цикле, в файл
//Если без eps, то сравнения такие: x<=newX<=x+dx
+
    }
if (((x+dx) - xAns>-eps) && (xAns - x>-eps))
+
    out.close();    // закрытие файла после записи в него значений
{
+
    D.Viv();
//Линейная интерполяция
+
    std::cout << std::endl << "y ";
x1 = x;
+
    for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран
x2 = x + dx;
+
    {
y1 = fx[i];
+
        std::cout << B[i] << " ";
y2 = fx[i + 1];
+
    }
K = (y2 - y1) / (x2 - x1);
 
B = (y2*x1 - y1*x2) / (x1 - x2);
 
//Вычисления значения функции в заданной точке с помощью линейной интерполяции
 
return K*xAns + B;
 
}
 
}
 
 
}
 
}
 
+
void Func::operator +(Func D)   // перегрузка оператора '+'
int main()
 
 
{
 
{
//Включение поддержки русского языка в консоли
+
    PluFunc(D);                         // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1+f2 будет работать аналогично записи f1.PluFunc(f2)
setlocale(LC_ALL, "Russian");
+
}
//Объявление трех переменных типа fun
+
void Func::MinFunc (Func D)   // функция, линейно вычитающая значения второй функции из значений первой функции
fun a, b, c;
+
{
//Считывания первых дискретных значений из файла inputA.txt
+
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
a.readFile("inputA.txt");
+
    for(int i=0; i<=D.j; ++i)  // создание цикла, повторяющегося (D.j+1) раз
//Считывания вторых дискретных значений из файла inputB.txt
+
    {
b.readFile("inputB.txt");
+
        B[i]=B[i]-D.A[i];   // вычитание значений второй функций из значений первой для одного и того же значения переменной
 
+
    }
//Первая функция
+
    for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
a.writeFile("outputA.txt");
+
    {
//Вторая функция
+
        out << B[i] << '\n';   // запись значений, полученных в предыдущем цикле, в файл
b.writeFile("outputB.txt");
+
    }
 
+
    out.close();   // закрытие файла после записи в него значений
c = a + b;
+
    D.Viv();
//Результат сложения двух функций
+
    std::cout << std::endl << "y ";
c.writeFile("outputAaddB.txt");
+
    for (int i=0; i<=D.j; ++i) // аналогичный предыдущему цикл, выводящий значения на экран
 
+
    {
 
+
        std::cout << B[i] << " ";
c = a - b;
+
    }
//Результат вычитания второй функции из первой
+
}
c.writeFile("outputAsubB.txt");
+
void Func::operator -(Func D)  // перегрузка оператора '-'
 
+
{
c = a*b;
+
    MinFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1-f2 будет работать аналогично записи f1.MinFunc(f2)
//Результат умножения двух функций
 
c.writeFile("outputAmultiB.txt");
 
 
 
c = a / b;
 
//Результат деления первой функции на вторую
 
c.writeFile("outputAdivB.txt");
 
 
 
//У первой функции изменили шаг на 0.5
 
a.changeDx(0.5);
 
//Вывели её дискретные значения
 
a.writeFile("outputChangeDx.txt");
 
 
 
//Функция, которая аппроксимирует её кусочно линейная.
 
//Для примера нашли значение аппроксимируещей функции в точке не совпадающей с дискретными значениями.
 
printf("Значение в точке 1.8 первой функции %.5lf\n", a.getX(1.8));
 
 
 
//Нужно чтобы окно консоли автоматически не закрылось
 
system("pause");
 
return 0;
 
 
}
 
}
</syntaxhighlight>
+
void Func::UmnFunc (Func D)    // функция, линейно переумножающая значения функций
</div>
+
{
 
+
     std::ofstream out("zap.txt");    // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
 
+
    for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+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 здесь]
+
        B[i]=B[i]*D.A[i];   // умножение значений первой функций на значенийя второй для одного и того же значения переменной
 
+
    }
'''[[Степанянц Степан]]'''
+
    for (int i=0; i<=D.j; ++i)     // создание цикла, рассчитанного на то же количество раз, что и предыдущий
+
    {
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.Данныеберутся из файла.
+
         out << B[i] << '\n';   // запись значений, полученных в предыдущем цикле, в файл
<div class="mw-collapsible-content">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
 
 
 
 
#include <iostream>
 
#include <vector>
 
#include <math.h>
 
#include <fstream>
 
#include <stdio.h>
 
#include <string>
 
#include <time.h>
 
 
 
using namespace std;
 
 
 
class func {
 
     vector <double> vals;
 
    double a, b, step, sz;
 
 
 
public:
 
    func (string fil) { //конструктор для ввода функции из файла
 
        ifstream f(fil.c_str());
 
        double a, b, step, y;
 
        f >> a >> b >> step; //вводим основные значения из файла
 
        this->step = step;
 
        this->sz = (int)((b - a) / step + 1); //считаем размер
 
        this->a = a, this->b = b;
 
        for (int i = 0; i < this->sz; i++) {
 
            f >> y;
 
            this->vals.push_back(y); //считываем и записываем значения из файла
 
        }
 
         f.close();
 
 
     }
 
     }
     func () {} //еще один конструктор
+
     out.close();    // закрытие файла после записи в него значений
     func operator + (func a) { // эта и ближайшие четыре метода -- калькулятор функций
+
     D.Viv();
        func f = *new func(); //создаем новый экземпляр класса, ответ
+
    std::cout << std::endl << "y ";
        for (int i = 0; i < sz; i++) {
+
    for (int i=0; i<=D.j; ++i)   // аналогичный предыдущему цикл, выводящий значения на экран
            f.vals.push_back(this->vals[i] + a.vals[i]); // складываем покоординатно
+
    {
        }
+
        std::cout << B[i] << " ";
        f.step = a.step; // копируем все значения в ответ (возможно, это можно сделать гораздо проще и не писать 4*4 строк но почему-то ничего умнее я не придумал)
+
    }
        f.a = a.a;
+
}
        f.b = a.b;
+
void Func::operator *(Func D)  // перегрузка оператора '*'
         f.sz = a.sz;
+
{
        return f;
+
    UmnFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1*f2 будет работать аналогично записи f1.UmnFunc(f2)
 +
}
 +
void Func::DelFunc (Func D)    // функция, линейно делящая значения первой функци на значения второй функции
 +
{
 +
    std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
 +
    for(int i=0; i<=D.j; ++i)    // создание цикла, повторяющегося (D.j+1) раз
 +
    {
 +
         B[i]=B[i]/D.A[i];       // деление значений первой функций на значенийя второй для одного и того же значения переменной
 
     }
 
     }
     func operator - (func a) {
+
     for (int i=0; i<=D.j; ++i)     // создание цикла, рассчитанного на то же количество раз, что и предыдущий
        func f = *new func();
+
    {
        for (int i = 0; i < a.sz; i++) {
+
        out << B[i] << '\n';       // запись значений, полученных в предыдущем цикле, в файл
            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) {
+
     out.close();    // закрытие файла после записи в него значений
        func f = *new func();
+
    D.Viv();
        for (int i = 0; i < a.sz; i++) {
+
    std::cout << std::endl << "y ";
            f.vals.push_back(this->vals[i] * a.vals[i]);
+
    for (int i=0; i<=D.j; ++i)     // аналогичный предыдущему цикл, выводящий значения на экран
        }
+
    {
        f.step = a.step;
+
        std::cout << B[i] << " ";
        f.a = a.a;
 
        f.b = a.b;
 
        f.sz = a.sz;
 
        return f;
 
 
     }
 
     }
     func operator / (func a) {
+
}
        func f = *new func();
+
void Func::operator /(Func D)  // перегрузка оператора '/'
        for (int i = 0; i < a.sz; i++) {
+
{
            f.vals.push_back(this->vals[i] / a.vals[i]);
+
    DelFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1/f2 будет работать аналогично записи f1.DelFunc(f2)
        }
+
}
         f.step = a.step;
+
void Func::In (Func D)     // функция, интерполирующая первую функцию по второй
         f.a = a.a;
+
{
         f.b = a.b;
+
    double l=c/D.c;    // создаем переменную, которой присваиваем значение, обозначающее, во сколько раз один шаг больше другого
        f.sz = a.sz;
+
    c=D.c;      // приводим больший шаг к меньшему значению
        return f;
+
    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();
 +
}
  
    pair<double, double> approx() { //аппроксимация. это все из наших лаб по физике, тут сплошная математика, никакого программирования
 
        double mid = 0;
 
        for (int i = 0; i < this->sz; i++) {
 
            mid += this->a + i * this->step;
 
        }
 
        mid /= this->sz;
 
        double d = 0;
 
        for (int i = 0; i < this->sz; i++) {
 
            d += pow((this->a + i * this->step - mid), 2.);
 
        }
 
        double a = 0;
 
        for (int i = 0; i < this->sz; i++) {
 
            a += (this->a + i * this->step - mid) * this->vals[i];
 
        }
 
        a /= d;
 
        double midy = 0;
 
        for (int i = 0; i < this->sz; i++) {
 
            midy += this->vals[i];
 
        }
 
        midy /= this->sz;
 
        double c = midy - a * mid;
 
        return {a, c}; //{x,y} возвращает пару (на самом деле не пару а просто какой-нибудь объект) с первым значением x и вторым y
 
    }
 
  
    func inter(double step) {
 
        func f = *new func(); //ответ
 
        double curr2, curr1;
 
        int j = 0;
 
        f.a = this->a, f.b = this->b, f.step = step, f.sz = (int)((b - a) / step + 1);
 
        for (int i = 0; i < f.sz; i++) {
 
            curr2 = a + i * step;
 
            curr1 = a + j * this->step;
 
            while (curr1 + this->step <= curr2) {
 
                j++, curr1 += this->step;
 
            }
 
            if (curr1 == curr2) {
 
                f.vals.push_back(this->vals[j]);
 
                continue;
 
            }
 
            f.vals.push_back((this->vals[j + 1] - this->vals[j]) * (curr2 - curr1) / this->step + this->vals[j]);//я хз, тут видимо какая-то математика
 
        }
 
        return f;
 
    }
 
    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();
 
  
     }
+
#include <iostream>
};
+
#include <fstream>
 +
#include "Func.h"
 +
 
 +
using namespace std;
 +
double m,n,o, m1, n1, o1;
 +
int a;
 +
char b;
 +
 
 +
int main()
 +
{
 +
    cout << "Enter the beginning, the end and the step of a function." << endl; // ввод опорных значений первой функции: начало, конец, шаг;
 +
    cin >> m >> n >> o; // считывание значений
 +
    cout << "Enter the beginning, the end and the step of another function." << endl; // ввод опорных значений второй функции: начало, конец, шаг;
 +
    cin >> m1 >> n1 >> o1; // считывание значений
 +
    Func F(m,n,o); // создание объекта класса Func, определяющий первую функцию
 +
    cout << "The first function is" << endl; F.Viv(); cout << endl << "y ";
 +
    F.DefFunc(); // определение первой функции через создание массива с ее значениями
 +
    cout << endl;
 +
    Func F1(m1,n1,o1); // создание объекта класса Func, определяющий вторую функцию
 +
    cout << "The second function is" << endl; F1.Viv(); cout << endl << "y ";
 +
    F1.DefFunc(); // определение второй функции через создание массива с ее значениями
 +
    cout << endl;
 +
    cout << "As two functions have different steps, we made the interpolation of the first function." << endl;
 +
    F.In(F1); // линейная интерполяция первой функции по второй
 +
    cout << endl;
 +
    cout << "What do you want to do with these functions?" << '\n' << "Enter 1 to sum them;" << '\n' << "Enter 2 to subtract the second from the first;" << '\n' << "Enter 3 to multiply them;" << '\n' << "Enter 4 to divide first by second" << endl;
 +
     cin >> a;
 +
    if (a==1)
 +
    {cout << "Function 1 + function 2 =" << '\n'; F+F1;}   // сложение двух функций с одинаковым шагом и интервалом
 +
    else if (a==2)
 +
    {cout << "Function 1 - function 2 =" << '\n'; F-F1;}   // вычитание двух функций с одинаковым шагом и интервалом
 +
    else if (a==3)
 +
    {cout << "Function 1 * function 2 =" << '\n'; F*F1;}  // умножение двух функций с одинаковым шагом и интервалом
 +
    else if (a==4)
 +
    {cout << "Function 1 / function 2 =" << '\n'; F/F1;}  // деление двух функций с одинаковым шагом и интервалом
 +
    cout << endl;
 +
    cout << "Enter 5 to do the approximation of the result function" << endl;  // пользователь сам выбирает, выполнять ли аппроксимацию;
 +
    cout << "Otherwise enter 6 to quit" << endl;
 +
    cin >> a;
 +
    if (a==5)
 +
    {cout << "Appromaximation:" << endl;
 +
    F.App();}  // аппроксимация
 +
    return 0;
 +
}
 +
 
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Савельева Ольга]]'''
 +
 +
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения.
 +
<div class="mw-collapsible-content">
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
//Бибилотека необходимая для возможности включения русского языка в консоли
 +
#include <locale.h>
  
int main() {
+
class fun
    string fil;
+
{
    cout << "Input the file name with the function values\n";
+
/*
    cin >> fil;
+
fx - массив с дискретными значениями функции
    func f = *new func(fil);
+
a - начало отрезка определения функции
    int a;
+
b - конец отрезка определения функции
    char ch;
+
dx - шаг
    double st;
+
*/
    while (true) {
+
double *fx, a, b, dx;
        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";
+
//Чтобы очусть ошибки округления в вещественных числах при сравнениях используется константа eps.
        cin >> a;
+
//К примеру два вещественных числа x и y сравниваются не так x>=y, а так x-y>=-eps.
        if (a == 4) {
+
const double eps = 1e-10; //1e-10 это тоже самое что 0.0000000001
            cout << "input file name to write to\n";
 
            cin >> fil;
 
            f.write(fil);
 
        }
 
        if (a == 3) {
 
            auto t = f.approx();
 
            cout << "Approximate line equation is y = " << t.first << " * x + " << t.second << '\n';
 
        }
 
        if (a == 2) {
 
            cout << "input step to interpolate\n";
 
            cin >> st;
 
            f = f.inter(st);
 
        }
 
        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>
 
  
 +
public:
 +
//Коструктор по умолчанию
 +
fun();
 +
//Конструктор копирования
 +
fun(fun &tmp);
 +
//Деструктор
 +
~fun();
  
<br>'''[[Нарядчиков Александр]]'''<br>
+
//Перегруженные операторы. Ключевое слово const в конце означает, что объект от которого вызвается метод не изменяется
'''Инструкция:''' Пользователю достаточно просто запустить программу.<br>
+
const fun operator+(const fun& right) const;
'''Описание программы:''' В окне рисуются графики с разным шагом, количеством точек, начальными и конечными координатами, по клавише 'G' происходит их кубическая интерполяция, также рисуется график их суммы. По клавише 'S' можно сохранить полученный график в текстовый документ в виде координат его точек. По клавише 'L' можно загрузить график из текстовый документа, и он появится в окне программы. Также происходит линейная аппроксимация графика суммы, и график аппроксимации рисуется на экран<br>
+
const fun operator-(const fun& right) const;
'''Описание алгоритма:''' Вся графика написана с помощью библиотек OpenGL и GLUT. Кубическая интерполяция написана с помощью кривых Безье(интерполяция по четырем точкам - кубическая кривая). При сложение двух графиков происходит их интерполяция, для приведения их к общему шагу. Линейная аппроксимация написана с помощью метода наименьших квадратов<br>
+
const fun operator*(const fun& right) const;
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
const fun operator/(const fun& right) const;
"'''T05GRAPH.CPP'''"
+
const fun& operator=(const fun& right);
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
/* FILENAME: T05GRAPH.CPP
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#include "GRAPH.H"
+
//Метод считывания из файла
 +
void readFile(const char *path);
 +
//Метод вывода в файл
 +
void writeFile(const char *path);
  
/* Глобальные переменные */
+
//Метод изменения шага
// Глобальная переменная, хранящая время в секундах с момента старта программы
+
void changeDx(double newDx);
double SyncTime;
+
//Метод вычисления значения в заданной точке
// Глобальные переменные для отслеживания нажатия клавиш
+
double getX(double x1);
bool IsGraph, IsSave, IsLoad, IsLoaded;
+
};
  
/* Timer function */
+
//В конструкторе по умолчанию все просто.
// Подсчет времени
+
fun::fun()
void Timer( void )
 
 
{
 
{
long t;
+
a = b = dx = 0;
static long StartTime = -1;
+
fx = NULL;
 +
}
  
t = clock();
+
//Конструктор копирования
if (StartTime == -1)
+
fun::fun(fun &tmp)
StartTime = t;
+
{
SyncTime = (double)(t - StartTime) / CLOCKS_PER_SEC;
+
int i, n;
} /* End of 'Timer' function */
+
//Копирование свойств объекта 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];
 +
}
  
/* Display function */
+
//Деструктор
// Стандартная функция, вызываемая при перерисовке окна
+
fun::~fun()
void Display( void )
+
{
 +
//Освобождение памяти выделенной для массива дискретных значений
 +
if (fx != NULL) delete[] fx;
 +
}
 +
//Оператор сложения.
 +
const fun fun::operator+(const fun& right) const
 
{
 
{
graph G1(-15, 15, 0.1), G2(2, 10, 0.4), G3, G4;
+
//Создание результирующего объекта
 +
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];
  
// Запуск времени
+
//Возвращение результата
Timer();
+
return result;
 +
}
  
// Установка цвета закраски фона в белый
+
//Этот оператор аналогичен оператору сложение
glClearColor(1, 1, 1, 1);
+
const fun fun::operator-(const fun& right) const
// Очищаем цветовой буфер для создания нового изображения
+
{
glClear(GL_COLOR_BUFFER_BIT);
+
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];
  
glLoadIdentity();
+
return result;
glScaled(0.1 / (1366 / 768.0), 0.1, 0.1);
+
}
  
// Отрисовка осей X и Y
+
//Этот оператор аналогичен оператору сложение
glBegin(GL_LINE_STRIP);
+
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];
  
glColor3d(0, 0, 1);
+
return result;
glVertex2d(0, -1000);
+
}
glVertex2d(0, 1000);
 
  
glColor3d(1, 0, 0);
+
//Этот оператор аналогичен оператору сложение
glVertex2d(-1000, 0);
+
const fun fun::operator/(const fun& right) const
glVertex2d(1000, 0);
+
{
 +
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];
  
glEnd();
+
return result;
 +
}
  
/* Отрисовка графиков */
+
//Оператор присваивания
// Отрисовка первого графика и его интерполяция по клавише "G"
+
const fun& fun::operator=(const fun& right)
G1.Draw(sin);
+
{
if (IsGraph == 1)
+
//Проверка на самоприсваивание
G1.Interpolation_Draw(1.0 / 32);
+
if (this == &right)
 +
//Возвращение в качестве результата текущий объект
 +
return *this;
  
// Отрисовка второго графика и его интерполяция по клавише "G"
 
G2.Draw(log);
 
if (IsGraph == 1)
 
G2.Interpolation_Draw(1.0 / 32);
 
  
// Отрисовка графика суммы для первого и второго графиков
+
int i, n;
G3 = G2 + G1;
+
//Присваивание свойств объекта right текущему объекту
glColor3d(0, 1, 0);
+
a = right.a;
G3.Draw();
+
b = right.b;
// Аппроксимация графика суммы
+
dx = right.dx;
G3.Approximation();
+
//Вычисление количества дискретных значений
 +
n = (b - a) / dx + 1;
 +
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
 +
if (fx != NULL) delete[] fx;
 +
//Выделение необходимой памяти для хранения дискретных значений
 +
fx = new double[n];
  
// Сохранение графика по клавише "S"
+
//Копирование дискретных значений объекта right в текущий объект
if (IsSave == 1)
+
for (i = 0; i<n; ++i)
{
+
fx[i] = right.fx[i];
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;
+
return *this;
delete[] G1.Color;
+
}
delete[] G2.mas;
 
delete[] G2.Color;
 
delete[] G3.mas;
 
delete[] G3.Color;
 
delete[] G4.mas;
 
delete[] G4.Color;
 
  
glFinish();
+
/*
// Копируем вторичный буфер в окно
+
Метод считывания из файла
glutSwapBuffers();
+
path - путь к файлу из которого считывать
// Вызываем функцию обновления кадра
+
*/
glutPostRedisplay();
 
} /* End of 'Display' function */
 
  
/* Keyboard function */
+
void fun::readFile(const char *path)
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
 
void Keyboard( unsigned char Key, int X, int Y )
 
 
{
 
{
// Выход из программы
+
//Открытие файла для считывания
if (Key == 27)
+
FILE *in = fopen(path, "r");
exit(0);
+
int i, n;
// Отрисовка интерполированных графиков
+
//Считывание границ отрезка и шага из файла
else if ((Key == 'G') || (Key == 'g'))
+
fscanf(in, "%lf%lf%lf", &a, &b, &dx);
IsGraph = !IsGraph;
+
//Вычисление количества дискретных значений
// Сохранение графика суммы в файл
+
n = (b - a) / dx + 1;
else if ((Key == 'S') || (Key == 's'))
+
//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
IsSave = !IsSave;
+
if (fx != NULL) delete[] fx;
// Загрузка графика из файла
+
//Выделение необходимой памяти для хранения дискретных значений
else if ((Key == 'L') || (Key == 'l'))
+
fx = new double[n];
IsLoad = !IsLoad;
+
//Считывание дискретных значений из файла
// Открытие программы в полном экране
+
for (i = 0; i<n; ++i) fscanf(in, "%lf", &fx[i]);
else if ((Key == 'F') || (Key == 'f'))
+
//Закрытие файла
glutFullScreen();
+
fclose(in);
} /* End of 'Keyboard' function */
+
}
 +
 
 +
/*
 +
Метод вывода в файл
 +
path - путь к файлу в который нужно вывести
 +
*/
  
/* Main function */
+
void fun::writeFile(const char *path)
int main( int argc, char *argv[] )
 
 
{
 
{
// Инициализации OpenGL и GLUT
+
//Открытие файла для вывода
glutInit(&argc, argv);
+
FILE *out = fopen(path, "w");
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+
int i, n;
 +
double x = a;
 +
//Вычисление количества дискретных значений
 +
n = (b - a) / dx + 1;
 +
//Вывод информации о отрезке и шаге в файл
 +
fprintf(out, "[%.5lf, %.5lf] dx=%.5lf\n", a, b, dx);
 +
//Последовательный вывод пары (точка, значение в точке) в файл
 +
for (i = 0; i<n; ++i, x += dx)
 +
fprintf(out, "x=%.5lf f(x)=%.5lf\n", x, fx[i]);
 +
//Закрытие файла
 +
fclose(out);
 +
}
  
// Задача размеров и позиции окна
+
/*
glutInitWindowPosition(0, 0);
+
Метод изменения величины шага
glutInitWindowSize(500, 500);
+
*/
// Создание окна
+
void fun::changeDx(double newDx)
glutCreateWindow("T05GRAPH");
 
 
 
// Установка функций 'обратного вызова'
 
glutDisplayFunc(Display);
 
glutKeyboardFunc(Keyboard);
 
 
 
// Запускаем основной цикл построения
 
glutMainLoop();
 
return 0;
 
} /* End of 'main' function */
 
 
 
/* END OF 'T05GRAPH.CPP' FILE */
 
</syntaxhighlight>
 
"'''GRAPH.CPP'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
/* FILENAME: GRAPH.CPP
 
* LAST UPDATE: 17.01.2016
 
*/
 
 
 
#include "GRAPH.H"
 
 
 
/* Load Array of points function */
 
// Загрузка графика из файла по точкам
 
void graph::LoadArray( char *FileName )
 
 
{
 
{
// Создание указателя на тип FILE
+
int i, j, n, newN;
FILE *F;
+
double *newFx, x, newX, x1, y1, x2, y2, K, B;
 
+
//Вычисление количества старых дискретных значений
// Создание файла и открытие его в режиме чтения
+
n = (b - a) / dx + 1;
fopen_s(&F, FileName, "rt");
+
//Вычисление количества новых дискретных значений
 
+
newN = (b - a) / newDx + 1;
// Количество точек
+
//Выделение памяти под новые дискретные значения
fscanf(F, "%d", &N);
+
newFx = new double[newN];
// Шаг функции
+
//Определение первой точки в которой вычисляется новое дискретное значение
fscanf(F, "%lf", &Step);
+
newX = a;
// Начальная координата по X
+
//Переменная которая бежит по старым дискретным значениям
fscanf(F, "%lf", &MinX);
+
i = 0;
// Конечная координата по X
+
//Определение первой точки в которой вычисляется старое дискретное значение
fscanf(F, "%lf", &MaxX);
+
x = a;
+
//Цикл для формирования новых дискретных значений
// Выделение памяти под массив точек
+
for (j = 0; j<newN; ++j, newX += newDx)
mas = new vec[N];
 
 
 
// Заполнение массива точек из файла
 
for (int i = 0; i < N; ++i)
 
 
{
 
{
// Заполнение по X
+
//В цикле находим отрезок где лежит точка в которой нужно вычислить новое дискретное значение
fscanf(F, "%lf", &mas[i].X);
+
for (; i<n - 1; ++i, x += dx)
// Заполнение по Y
+
//Если без eps, то сравнения такие: x<=newX<=x+dx
fscanf(F, "%lf", &mas[i].Y);
+
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;
 +
}
  
// Закрытие файла
+
/*
fclose(F);
+
Метод вычисляет значение в точке xAns с помощью линейной интерполяции.
} /* End of 'LoadArray' function */
+
*/
 
+
double fun::getX(double xAns)
/* Fill mas function */
 
// Заполнение массива координат точек с цветом
 
void graph::Fill( double(*f)(double) )
 
 
{
 
{
// Выделение памяти под массив точек
+
int i, n;
mas = new vec[N];
+
double x, x1, y1, x2, y2, K, B;
// Выделение памяти под массив цветов
+
x = a;
Color = new vec[N];
+
//Вычисление количества дискретных значений
 
+
n = (b - a) / dx + 1;
// Заполнение массивов
+
//Ищем отрезок в котором лежит точка xAns
for (int i = 0; i < N; i++)
+
for (i = 0; i<n - 1; ++i, x += dx)
 
{
 
{
mas[i] = vec(MinX + i * Step, f(MinX + i * Step));
+
//Если без eps, то сравнения такие: x<=newX<=x+dx
Color[i] = vec::Rnd();
+
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;
 +
}
 
}
 
}
} /* End of 'Fill' function */
+
}
  
/* Draw graph function */
+
int main()
// Рисование заполненного графика на экран
 
void graph::Draw( void )
 
 
{
 
{
  // Задача размер точки
+
//Включение поддержки русского языка в консоли
glPointSize(1);
+
setlocale(LC_ALL, "Russian");
// Рисование
+
//Объявление трех переменных типа fun
glBegin(GL_POINTS);
+
fun a, b, c;
for (int i = 0; i < N; i++)
+
//Считывания первых дискретных значений из файла inputA.txt
glVertex2d(mas[i].X, mas[i].Y);
+
a.readFile("inputA.txt");
glEnd();
+
//Считывания вторых дискретных значений из файла inputB.txt
} /* End of 'Draw' function */
+
b.readFile("inputB.txt");
  
/* Draw graph function */
+
//Первая функция
// Рисование не заполненного еще графика на экран
+
a.writeFile("outputA.txt");
void graph::Draw( double(*f)(double) )
+
//Вторая функция
{
+
b.writeFile("outputB.txt");
// Заполнение массива
+
 
graph::Fill(f);
+
c = a + b;
 +
//Результат сложения двух функций
 +
c.writeFile("outputAaddB.txt");
  
// Задача цвета и размера точки
 
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 */
+
c = a - b;
// Рисование интерполированного графика на экран
+
//Результат вычитания второй функции из первой
void graph::Interpolation_Draw( double i_step )
+
c.writeFile("outputAsubB.txt");
{
 
// Коэффициент Катмулл-Рома
 
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];
 
  
// Значения для первого и последнего отрезков
+
c = a*b;
if (i == 0)
+
//Результат умножения двух функций
{
+
c.writeFile("outputAmultiB.txt");
P1 = (mas[1] - mas[0]) * alpha + mas[0];
+
 
Color1 = (mas[1] - mas[0]) * alpha + mas[0];
+
c = a / b;
}
+
//Результат деления первой функции на вторую
else
+
c.writeFile("outputAdivB.txt");
{
 
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);
+
//У первой функции изменили шаг на 0.5
glBegin(GL_LINE_STRIP);
+
a.changeDx(0.5);
for (double t = 0; t <= 1; t += i_step)
+
//Вывели её дискретные значения
{
+
a.writeFile("outputChangeDx.txt");
vec p, color;
 
  
// Вычисление точки интерполированного графика по 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;
+
printf("Значение в точке 1.8 первой функции %.5lf\n", a.getX(1.8));
  
// Рисование
+
//Нужно чтобы окно консоли автоматически не закрылось
glColor3d(color.X / 10, 0, color.Y);
+
system("pause");
glVertex2d(p.X, p.Y);
+
return 0;
}
+
}
glEnd();
+
</syntaxhighlight>
}
+
</div>
} /* End of 'Interpolation_Draw' function */
 
  
/* Interpolation graph function */
 
// Интерполяция графика
 
graph graph::Interpolation( double i_step )
 
{
 
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 точкам
+
Скачать можно [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 здесь]
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;
 
}
 
}
 
  
return G_New;
 
} /* End of 'Interpolation' function */
 
  
/* Sum of 2 graphics function */
+
'''[[Сенников Иван]]'''
// Сложение двух графиков
+
graph graph::operator+( graph &G )
+
'''Суть программы:''' Программы позволяет задать 2 функции с любыми областями определения и любыми множествами значений, интерполировать их на любом шаге, аппроксимировать, а так же сложить 2 существующие функции. Программа написана в классе работы с функциями.
{
 
graph G_New, G1, G2;
 
int i, j;
 
  
// Заполнение параметров графика суммы
+
'''Идея:''' Класс работы с функциями содержит такие функции как функция введения данных функции - ее создание, перегрузки оператора сложения, линейных интерполяции и аппроксимации, выделения и освобождения памяти. Линейная интерполяция написана с помощью теории аналитической геометрии на плоскости, а линейная аппроксимация с помощью метода наименьших квадратов.
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);
 
  
// Поиск общего начала и конца графиков
+
Ссылка для скачиваний: [http://tm.spbstu.ru/Файл:Func.zip здесь].
for (i = 0; i < G1.N; i++)
 
if (fabs(G1.mas[i].X - G_New.MinX) <= Threshold)
 
break;
 
  
for (j = 0; j < G2.N; j++)
 
if (fabs(G2.mas[j].X - G_New.MinX) <= Threshold)
 
break;
 
  
// Заполнение графика суммы
+
'''[[Степанянц Степан]]'''
for (int k = 0; k < G_New.N; k++)
+
{
+
'''Краткое описание алгоритма :''' Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.Данныеберутся из файла.
G_New.mas[k].X = G_New.MinX + k * G_New.Step;
+
<div class="mw-collapsible-content">
G_New.mas[k].Y = G1.mas[i + k].Y + G2.mas[j + k].Y;
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
}
 
  
return G_New;
 
} /* End of 'Sum' function */
 
  
/* Save Array of points function */
+
#include <iostream>
// Сохранение графика в файл по точкам
+
#include <vector>
void graph::SaveArray( void )
+
#include <math.h>
{
+
#include <fstream>
// Создание указателя на тип FILE
+
#include <stdio.h>
FILE *F;
+
#include <string>
 
+
#include <time.h>
// Создание файла и открытие его в режиме записи
+
fopen_s(&F, "graph.txt", "wt");
+
using namespace std;
 
+
/* Запись в файл данных */
+
class func {
// Количество точек
+
    vector <double> vals;
fprintf(F, "%d\n", N);
+
    double a, b, step, sz;
// Шаг функции
+
fprintf(F, "%lf\n", Step);
+
public:
// Начальная координата по X
+
    func (string fil) { //конструктор для ввода функции из файла
fprintf(F, "%lf\n", MinX);
+
        ifstream f(fil.c_str());
// Конечная координата по X
+
        double a, b, step, y;
fprintf(F, "%lf\n", MaxX);
+
        f >> a >> b >> step; //вводим основные значения из файла
 
+
        this->step = step;
// Координаты всех точек
+
        this->sz = (int)((b - a) / step + 1); //считаем размер
for (int i = 0; i < N; ++i)
+
        this->a = a, this->b = b;
  fprintf(F, "%lf %lf ", mas[i].X, mas[i].Y);
+
        for (int i = 0; i < this->sz; i++) {
 
+
            f >> y;
// Закрытие файла
+
            this->vals.push_back(y); //считываем и записываем значения из файла
fclose(F);
+
        }
} /* End of 'SaveArray' function */
+
        f.close();
 
+
    }
/* Approximation of function function */
+
    func () {} //еще один конструктор
// Аппроксимация графика
+
    func operator + (func a) { // эта и ближайшие четыре метода -- калькулятор функций
void graph::Approximation( void )
+
        func f = *new func(); //создаем новый экземпляр класса, ответ
{
+
        for (int i = 0; i < sz; i++) {
double k, b, s1 = 0, s2 = 0, s3 = 0, s4 = 0;
+
            f.vals.push_back(this->vals[i] + a.vals[i]); // складываем покоординатно
 
+
        }
// Линейная аппроксимация
+
        f.step = a.step; // копируем все значения в ответ (возможно, это можно сделать гораздо проще и не писать 4*4 строк но почему-то ничего умнее я не придумал)
for (int i = 0; i < N; i++)
+
        f.a = a.a;
{
+
        f.b = a.b;
if (fabs(mas[i].X) < MAX && fabs(mas[i].Y) < MAX)
+
        f.sz = a.sz;
{
+
        return f;
s1 += mas[i].X * mas[i].Y;
+
    }//Перегрузки операторов
s2 += mas[i].X;
+
    func operator - (func a) {
s3 += mas[i].X * mas[i].X;
+
        func f = *new func();                 
s4 += mas[i].Y;
+
        for (int i = 0; i < a.sz; i++) {
}
+
            f.vals.push_back(this->vals[i] - a.vals[i]);    //Вычитание
}
+
        }
 
+
        f.step = a.step;
k = (N * s1 - s2 * s4) / (double(N) * s3 - s2 * s2);
+
        f.a = a.a;
b = (s4 - k * s2) / double(N);
+
        f.b = a.b;
 
+
        f.sz = a.sz;
// Задача цвета и ширины линии
+
        return f;
glColor3d(1, 0.5, 0);
+
    }
glLineWidth(1);
+
    func operator * (func a) {
// Рисование
+
        func f = *new func();
glBegin(GL_LINE_STRIP);
+
        for (int i = 0; i < a.sz; i++) {
glVertex2d(MinX, MinX * k + b);
+
            f.vals.push_back(this->vals[i] * a.vals[i]);  //умножение
glVertex2d(MaxX, MaxX * k + b);
+
        }
glEnd();
+
        f.step = a.step;
} /* End of 'Approximation' function */
+
        f.a = a.a;
 
+
        f.b = a.b;
/* End of 'GRAPH.CPP' file */
+
        f.sz = a.sz;
</syntaxhighlight>
+
        return f;
"'''GRAPH.H'''"
+
    }
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    func operator / (func a) {
/* FILENAME: GRAPH.H
+
        func f = *new func();
* LAST UPDATE: 17.01.2016
+
        for (int i = 0; i < a.sz; i++) {
*/
+
            f.vals.push_back(this->vals[i] / a.vals[i]);    // Деление
 
+
        }
#ifndef _GRAPH_H_
+
        f.step = a.step;
#define _GRAPH_H_
+
        f.a = a.a;
 
+
        f.b = a.b;
#define _CRT_SECURE_NO_WARNINGS
+
        f.sz = a.sz;
 
+
        return f;
#include <iostream>
+
    }
#include <stdio.h>
+
#include <stdlib.h>
+
    pair<double, double> approx() { //аппроксимация.
#include <math.h>
+
        double mid = 0;
#include <time.h>
+
        for (int i = 0; i < this->sz; i++) {
#include <GL\glut.h>
+
            mid += this->a + i * this->step;
 
+
        }
#define MAX 100
+
        mid /= this->sz;
 
+
        double d = 0;
using namespace std;
+
        for (int i = 0; i < this->sz; i++) {
 
+
            d += pow((this->a + i * this->step - mid), 2.);
/* Useful constants */
+
        }
const double Threshold = 1e-10;
+
        double a = 0;
const double Infinity = 1e+10;
+
        for (int i = 0; i < this->sz; i++) {
 
+
            a += (this->a + i * this->step - mid) * this->vals[i];
/* Vector representation type */
+
        }
class vec
+
        a /= d;
{
+
        double midy = 0;
public:
+
        for (int i = 0; i < this->sz; i++) {
double X, Y;
+
            midy += this->vals[i];
 
+
        }
/* Default constructor */
+
        midy /= this->sz;
vec( void )
+
        double c = midy - a * mid;
{
+
        return {a, c}; //{x,y} возвращает пару (на самом деле не пару а просто какой-нибудь объект) с первым значением x и вторым y
}
+
    }
 
+
/* Class constructor */
+
    func inter(double step) {
vec( double A ) : X(A), Y(A)
+
        func f = *new func(); //ответ
{
+
        double curr2, curr1;
}
+
        int j = 0;
 
+
        f.a = this->a, f.b = this->b, f.step = step, f.sz = (int)((b - a) / step + 1);
/* Class constructor */
+
        for (int i = 0; i < f.sz; i++) {
vec( double A, double B ) : X(A), Y(B)
+
            curr2 = a + i * step;
{
+
            curr1 = a + j * this->step;
}
+
            while (curr1 + this->step <= curr2) {
 
+
                j++, curr1 += this->step;
static double R0( void )
+
            }
{
+
            if (curr1 == curr2) {
return rand() / (double)RAND_MAX;
+
                f.vals.push_back(this->vals[j]);
} /* End of 'R0' function */
+
                continue;
 
+
            }
static vec Rnd( void )
+
            f.vals.push_back((this->vals[j + 1] - this->vals[j]) * (curr2 - curr1) / this->step + this->vals[j]);//я хз, тут видимо какая-то математика
{
+
        }
return vec(R0(), R0());
+
        return f;
} /* End of 'Rnd' function */
+
    }
 
+
    void write(string fil) { //запись. чтобы записать не в файл, а в консоль вывести, надо передать "-1"
/* The functions of operations on vectors */
+
        ofstream f(fil.c_str());
 
+
        if (fil != "-1") {
/* Vector = vector function */
+
            f << this->a << ' ' << this->b << ' ' << this->step << '\n';
vec operator=( vec &B )
+
        }
{
+
        else
X = B.X;
+
            cout << this->a << ' ' << this->b << ' ' << this->step << '\n';
Y = B.Y;
+
        for (int i = 0; i < sz; i++) {
 
+
            if (fil != "-1")
return B;
+
                f << this->vals[i] << '\n';
} /* end of 'operator+' function */
+
            else
 
+
                cout << this->vals[i] << '\n';
/* Vector add vector function */
+
        }
vec operator+( const vec &B ) const
+
        f.close();
{
+
return vec(X + B.X, Y + B.Y);
+
    }
} /* end of 'operator+' function */
+
};
 
+
/* Vector sub vector function */
+
int main() {
vec operator-( const vec &B ) const
+
    string fil;
{
+
    cout << "Input the file name with the function values\n";
return vec(X - B.X, Y - B.Y);
+
    cin >> fil;
} /* end of 'operator-' function */
+
    func f = *new func(fil);
 +
    int a;
 +
    char ch;
 +
    double st;
 +
    while (true) {
 +
        cout << "what do you want to do?\n1-math operation\n2-interpolation\n3-approximation\n4-write to file\n5-read values from file\n6-quit\n";
 +
        cin >> a;
 +
        if (a == 4) {
 +
            cout << "input file name to write to\n";
 +
            cin >> fil;
 +
            f.write(fil);
 +
        }
 +
        if (a == 3) {
 +
            auto t = f.approx();
 +
            cout << "Approximate line equation is y = " << t.first << " * x + " << t.second << '\n';
 +
        }
 +
        if (a == 2) {
 +
            cout << "input step to interpolate\n";
 +
            cin >> st;
 +
            f = f.inter(st);
 +
        }
 +
        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>
  
vec operator-( void ) const
+
'''[[Сюрис Александр]]'''
{
+
Задаются две функции с разными шагами и начальными и конечными значениями.  Аппроксимирует одну функцию по шагу другой и складывает/умножает/вычитает/делит их
return vec(-X, -Y);
 
} /* end of 'operator-' function */
 
  
/* Vector mul number 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 тут].
vec operator*( const double N ) const
 
{
 
return vec(X * N, Y * N);
 
} /* end of 'operator*' function */
 
  
/* Vector div number function */
+
<div class="mw-collapsible-content">
vec operator/( const double N ) const
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
{
 
return vec(X / N, Y / N);
 
} /* end of 'operator/' function */
 
  
/* Vector dot vector function */
+
#include <iostream>
double operator&( const vec &B ) const
+
#include <vector>
{
+
#include<math.h>
return double(X * B.X + Y * B.Y);
 
} /* end of 'operator&' function */
 
  
vec & operator+=( const vec &B )
+
using namespace std;
{
+
class f{
X += B.X;
+
    private:
Y += B.Y;
+
    double st, en, d; //начало, конец, дельта
 
+
    vector<double> v;//вектор, содержащий y
return *this;
+
    public:
} /* end of 'operator+=' function */
+
    f(double _st, double _en, double _d, vector<double> _v){
 
+
        st=_st;
vec & operator-=( const vec &B )
+
        en=_en;
{
+
        d=_d;
X -= B.X;
+
        for(int i=0;i<_v.size();i++) //копируем массив, который вводим в консоль
Y -= B.Y;
+
            v.push_back(_v[i]);
 
+
        //return *this;
return *this;
+
    }
} /* end of 'operator-=' function */
+
    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));
  
vec & operator*=( const double N )
+
        vector<double> v1;//вектор, содержащий проинтерполированную функцию
{
+
            for(int i=0; i<=(en-st)/d; i++)
X *= N;
+
                v1.push_back(a*(st+i*d)+b);//добавление значений проинтерполированной ф-ции с шагом другой функции
Y *= N;
+
        return f(_st,_en,_d,v1);
  
return *this;
+
    }
} /* end of 'operator*=' function */
 
  
vec & operator/=( const double N )
+
    f operator +(f x){//оператор сложения
{
+
        double _en,_st,_d;
X /= N;
+
        _en=min(en,x.en); //поиск области пересечения
Y /= N;
+
        _st=max(st,x.st);
 
+
        if (_en>_st){//проверяем, пересекаются ли функции
return *this;
+
            vector<double> _v;
} /* end of 'operator/=' function */
+
            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);
 +
            }
 +
        }
 +
    }
  
double operator!( void ) const
+
    f prot(){ //поиск противоположной функции
{
+
        for (int i=0; i<=(en-st)/d; i++)
return double(X * X + Y * Y);
+
            v[i]=(-1)*v[i];
} /* end of 'operator!' function */
+
        return *this;
 +
    }
  
/* Access vector components by index function */
+
    f operator - (f x){ //разность функций
double operator[]( const int i ) const
+
        return(*this + x.prot());
{
+
    }
switch (i)
 
{
 
case 0:
 
return double(X);
 
case 1:
 
return double(Y);
 
}
 
} /* end of 'operator[]' function */
 
  
/* Normalizing vector function */
+
f operator *(f x){//оператор умножения
vec & Normalize( void )
+
        double _en,_st,_d;
{
+
        _en=min(en,x.en); //поиск области пересечения
double len = !*this;
+
        _st=max(st,x.st);
 +
        if (_en>_st){//проверяем, пересекаются ли функции
 +
            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 obr(){
 +
  for (int i=0; i<=(en-st)/d; i++)
 +
            v[i]=1/v[i];
 +
        return *this;
 +
}
  
if (len != 1 && len != 0)
+
f operator /(f x){
*this /= sqrt(len);
+
return(*this*x.obr());
return *this;
+
}
} /* end of 'Normalize' function */
 
}; /* end of 'vec' class */
 
  
/* Graph class */
+
    void vivod(){ //вывод
class graph
+
    for(int i=0; i<v.size(); i++)
{
+
        cout<<v[i]<<" ";
public:
+
 
double MinX, MaxX, Step; // Начальная координата по X; Конечная координата по X; Шаг функции
+
    }
int N; // Количество точек
+
};
vec *mas, *Color; // Массивы точек и цветов
+
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);
 +
    }
  
/* Default constructor */
+
    cout << "Проделаем ровно то же самое для 2 функции ";
graph( void )
+
    cout << "Введите начала и конец отрезка и дельту: ";
{
+
    cin >> a1 >> b1 >> d1;
MinX = -10, MaxX = 10, Step = 0.1, N = 200;
 
}
 
  
/* Class constructor */
+
    amount2=(b1-a1)/d1+1;
graph( double _MinX, double _MaxX, double _Step ) : MinX(_MinX), MaxX(_MaxX), Step(_Step)
+
    vector<double>y;
{
+
    cout << "Введите " << amount2 << " значений функции на данном интервале:";
N = (int)((MaxX - MinX) / Step);
+
    for (int i=0; i<amount2; i++)
// Выделение памяти
+
    {
mas = new vec[N];
+
        cin>>t;
Color = new vec[N];
+
        y.push_back(t);
}
+
    }
 
+
    f g(a,b,d,x);
/* Load Array of points function */
+
    f h(a1,b1,d1,y);
void LoadArray( char *FileName );
+
 
 
+
    cout<<"Выберете дейстивя с функциями: +, -, *, \ " << endl;
/* Fill mas function */
+
    cout<<"Введите число, соответсвующее порядковому номеру операции(1-4) - ";
void Fill( double(*f)(double) );
+
    cin>>o;
 
+
    if(o==1){              //по невыясненным причинам одновременно написанные слева идущие if -ы не работают,
/* Draw graph function */
+
        cout<<"Сумма:";    //но если заккоментить их и менять знак + в скобке на другие, то все работает
void Draw( double(*f)(double) );
+
        (g+h).vivod();
 
+
 
/* Draw graph function */
+
    }
void Draw( void );
+
 
 
+
    if(o==2){
/* Interpolation draw graph function */
+
        cout<<"Разность:"
void Interpolation_Draw( double i_step );
+
        (g-h).vivod();
 
+
 
/* Interpolation graph function */
+
    }
graph Interpolation( double i_step );
+
 
 
+
    if(o==3){
/* Sum of 2 graphics function */
+
        cout<<"Произведение:"
graph operator+( graph &G );
+
        (g*h).vivod();
 
+
 
/* Save Array of points function */
+
 
void SaveArray( void );
+
    }
 
+
 
/* Approximation of function function */
+
    if(o==3){
void Approximation( void );
+
        cout<<"Отношение:"
}; /* end of 'graph' class */
+
        (g/h).vivod();
 
+
    }
#endif /* _GRAPH_H_ */
+
 
 
+
 
/* End of 'GRAPH.H' file */
+
}
 +
 
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
'''[[Тимошенко Валентина]]'''
 +
 
 +
'''Краткое описание алгоритма''': в классе создаются две различные функции, а также функции для осуществления арифметических операций - сложения, вычитания, умножения и деления. Кроме того, созданы функции интерполяции и аппроксимации результата. Все результаты записываются в файлы, названия которых выводятся на экран в процессе работы программы.
 +
 
 +
'''Инструкция к программе''': при запуске программа предлагает ввести начало интервала, его конец и шаг для обеих функций. Далее пользователь выбирает одну из предложенных арифметических операций - сложение, вычитание, умножение или деление. После проведения вычислений программа предлагает пользователю интерполировать и аппроксимировать результат выбранной арифметической операции. Пользователь может давать команды на выполнение арифметических операций неограниченное число раз, программа завершает работу по команде пользователя.
 +
 
 +
 
 +
Скачать программу можно здесь: [http://tm.spbstu.ru/Файл:Program2.zip].
 +
 
 +
<div class="mw-collapsible-content">
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream> ///программа, перегружающая операторы для работы с двумя функциями,
 +
#include <fstream>  ///интерполирующая и аппроксимирующая результат арифметических операций над этими функциями
 +
#include <math.h>
 +
 
 +
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>
 
</syntaxhighlight>
 
</div>
 
</div>
[http://tm.spbstu.ru/File:T05GRAPH.7z Скачать архив]
 
<br>
 

Текущая версия на 06:15, 17 июня 2016

Абрамов Игорь

Алгоритм: функции хранятся в программе как массив точек, заданных с определённым шагом по X на заданном отрезке. Вводить значения функции в программу можно двумя способами: с помощью математических функций из стандартных библиотек, указывая начало и конец отрезка, а также шаг, с которым определена функция, и считывая координаты точек из файла, предварительно считав их количество. Далее с любыми функциями можно производить следующие действия и их комбинации: сложение, вычитание, кубическая интерполяция и линейная аппроксимация. При этом результат каждого из этих действий - новая функция, с которой можно продолжать работу. Функции можно выводить на экран с помощью средств графической библиотеки OpenGL, а также печатать её значения в файл.

Инструкция: пользователь вводит необходимые действия с функциями в функции Display. На данный момент при запуске программы можно увидеть пример её работы: первая функция считывается из файла, интерполируется и выводится на экран. Затем вторая функция вводится из библиотеки math.h интерполируется и выводится на экран. Затем функции суммируются, интерполируются и выводятся на экран. File:Func_Abramov.rar

Ссылка на скачивание: [1]

Андреева Полина

Инструкция к программе: пользователь должен ввести начало, конец и шаг. Создается две функции. Затем на экране появляется один из знаков арифметических действий. Пользователь выбирает один из знаков. Создается третья функция. Пользователь вводит второй шаг. Функция интерполируется по этому новому шагу, а затем аппроксимируется. Краткое описание алгоритма : в классе создается две функции(с помощью массивов). Так же в классе есть такие методы: перегрузка арифм операций, интерполяция, аппроксимация, вывод массивов на экран и их сохранение в файл. Сначала создается два массива для функций. Затем с помощью перегрузки эти два массива складываются/умножаются/делятся/вычитаются и записываются опять в этот массив. В методе перегрузки сразу вызывается интерполяция и аппроксимация. Программа

  1 #include <iostream>
  2 #include <fstream>
  3 #include "math.h"
  4 using namespace std;
  5 class func
  6 {
  7 private:
  8     double *mass1, *mass, *masss ;
  9     double  AmountDouble, Begin, End, Step, Step2;
 10 public:
 11     int  AmountInt;
 12     func ( double _Begin, double _End, double _Step ):Begin(_Begin), End(_End), Step(_Step)
 13     {
 14         AmountDouble=((End-Begin)/Step)+1;///количество точек с данным шагом
 15         AmountInt=static_cast<int>(AmountDouble);///так как количество это целое число, то округляем
 16 
 17     }
 18 
 19     void massiv1() ///создание первой функции х^3
 20     {
 21         mass=new double[AmountInt];
 22         for (int l=0; l<AmountInt; l++)
 23         {
 24             mass[l] =pow((l*Step+Begin),3);
 25         }
 26         cout << "y=x^3 \n";
 27     }
 28     void massiv2() ///создание второй функции sin(x)
 29     {
 30         mass=new double[AmountInt];
 31         for (int l=0; l<AmountInt; l++)
 32         {
 33             mass[l] =sin(l*Step+Begin);
 34         }
 35         cout << "y=sin(x) \n";
 36     }
 37 
 38     void interpolation(double __Begin, double __End,  double __Step)
 39     {
 40 
 41         double NewAmount=((__End-__Begin)/__Step) + 1;///количество точек для нового шага
 42         int NewAmountInt=static_cast<int>(NewAmount);
 43         for (int i=0; i<NewAmountInt; i++)///i-это точки функции с новыми шагами
 44         {
 45             mass1 = new double[NewAmountInt];
 46             double x = i*__Step+__Begin;///значения х в новых точках
 47             double x0=(static_cast<int>((x-__Begin)/Step)) * Step+__Begin;///значение х в точке интерполяции
 48             ///стоящей ДО новой точки
 49             double x1=x0+Step;///точка интерполяции ПОСЛЕ новой точки, т.е к предыдущей прибавляем СТАРЫЙ шаг
 50             int i0=(static_cast<int>((x-__Begin)/Step));///это нужно для массива, значение массива в i0 соответстует значению функции в x0
 51             int i1=i0+1;
 52             mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
 53             cout << "y("<<i<< ") = " << mass1[i] <<endl<<endl; ///вывод интерполяции на экран
 54             std::ofstream fout("Interpol.txt",ios::app);///сохранение в файл
 55             fout<<i<<" "<<mass1[i]<<" \n";
 56             fout.close();
 57         }
 58         AmountInt=NewAmountInt;
 59         delete[] mass;
 60         mass=mass1;
 61         cout<<"end of interpol";
 62     }
 63 
 64     void approximation(double __Begin, double __End, double __Step)
 65 
 66     {
 67         double SumXMass=0;///это сумма умножений x на значение функции в этом x для всех значений
 68         double SumX=0;///сумма всех значений x
 69         double SumMass=0;///сумма всех значений функции в точках x
 70         double SumXX=0;///сумма всех квадратов значений x
 71         mass1 = new double[AmountInt];
 72         double x;
 73         for (int i=0; i<AmountInt; i++)
 74         {
 75             x=i*__Step+__Begin;///такие значения принимает x в точках по порядку i
 76             SumXMass=SumXMass+x*mass[i];
 77             SumX=SumX+x;
 78             SumMass=SumMass+mass[i];
 79             SumXX=SumXX+x*x;
 80 
 81         }
 82         double a=(SumXMass*AmountInt-SumX*SumMass)/(AmountInt*SumXX-SumX*SumX);
 83         double b=(SumMass-a*SumX)/AmountInt;
 84         if (b>0)
 85             cout<<"approximation "<<a<<"*x+"<<b<<endl;
 86         else if (b<0)
 87             cout<<"approximation "<<a<<"*x"<<b<<endl;
 88 
 89         for (int i=0; i<AmountInt; i++)
 90         {
 91             mass1[i] = a*(i*__Step+__Begin)+b;///такие значения принимает апроксимация
 92         }
 93         delete[] mass;
 94         mass=mass1;
 95         output();///вывод на экран
 96         SaveFile("approximation.txt");///сохранение в файл
 97         cout<<"end of appox";
 98 
 99     }
100 
101     func operator+( func f)///перегрузка оператора +
102     {
103         func newmass(Begin, End, Step);
104         masss=new double[AmountInt];///новая функция равная сумме данныйх функций
105         for (int i=0; i<AmountInt; i++)
106         {
107             masss[i] = mass[i] + f.mass[i];
108         }
109         delete [] mass;
110         mass=masss;
111         output();///вывод на экран резултата
112         SaveFile("f3.txt");///сохранение в файл
113         cout<<"enter new step";
114         cin>>Step2;
115         cout<<"interpolation: ";
116         interpolation(Begin,End,Step2);///интерполяция
117         cout<<" approximation: ";
118         approximation(Begin,End,Step2);///аппроксимация
119         return newmass;
120 
121     }
122 
123     func operator-( func f)
124     {
125         func newmass(Begin, End, Step);
126         masss=new double[AmountInt];
127         for (int i=0; i<AmountInt; i++)
128         {
129             masss[i] = mass[i] - f.mass[i];
130         }
131         delete [] mass;
132         mass = masss;
133         output();
134         SaveFile("f3.txt");
135         cout<<"enter new step";
136         cin>>Step2;
137         cout<<"interpolation: ";
138         interpolation(Begin,End,Step2);
139         cout<<" approximation: ";
140         approximation(Begin,End,Step2);
141         return newmass;
142     }
143     func operator/( func f)
144     {
145         func newmass(Begin, End, Step);
146         masss=new double[AmountInt];
147         for (int i=0; i<AmountInt; i++)
148         {
149             masss[i] = mass[i] / f.mass[i];
150         }
151         cout << " division: \n ";
152         delete [] mass;
153         mass = masss;
154         output();
155         SaveFile("f3.txt");
156         cout<<"enter new step";
157         cin>>Step2;
158         cout<<"interpolation: ";
159         interpolation(Begin,End,Step2);
160         cout<<" approximation: ";
161         approximation(Begin,End,Step2);
162         return newmass;
163     }
164     func operator*( func f)
165     {
166         func newmass(Begin, End, Step);
167         masss=new double[AmountInt];
168         for (int i=0; i<AmountInt; i++)
169         {
170             masss[i] = mass[i] * f.mass[i];
171         }
172         cout << " multiply: \n ";
173         delete [] mass;
174         mass = masss;
175         output();
176         SaveFile("f3.txt");
177         cout<<"enter new step";
178         cin>>Step2;
179         cout<<"interpolation: ";
180         interpolation(Begin,End,Step2);
181         cout<<" approximation: ";
182         approximation(Begin,End,Step2);
183         return newmass;
184     }
185 
186 
187     void output()///вывод функции на экран
188     {
189         for (int i=0; i<AmountInt; i++)
190         {
191             cout << "y("<<i<< ") = " << mass[i] <<endl;
192 
193         }
194     }
195 
196 
197     void SaveFile(char filename[])///сохранение функции в файл
198     {
199         std::ofstream fout(filename);
200         for (int l=0; l<AmountInt; l++)
201         {
202             fout<<l<<" "<<mass[l]<<" \n";
203         }
204 
205         fout.close();
206     }
207 };
208 
209 
210 
211 int main()
212 {
213 
214     double Begin1, End1, Step1, Step2;
215     cout<<" enter the beginning of the  function ";
216     cin>>Begin1;
217     cout<<"\n enter the end of the  function ";
218     cin>>End1;
219     cout<<"\n enter the step of the 1st function ";
220     cin>>Step1;
221 
222     func f1(Begin1,End1,Step1);///создание первой функции
223     f1.massiv1();
224     f1.output();
225     cout<<"\n ";
226     f1.SaveFile("f1.txt");
227 
228     func f2(Begin1,End1,Step1);///создание второй функции
229     f2.massiv2();
230     f2.output();
231     cout<<"\n ";
232     f2.SaveFile("f2.txt");
233     cout<<"\n";
234 
235     func f3(Begin1,End1,Step1);
236 
237     cout<<" \n \n choose 1 - sum , 2 - subtract, 3 - division, 4 - multiply \n";///выбор операции
238     int z;
239     cin>>z;
240     switch (z)
241     {
242     case 1:
243     {
244         f3=f1+f2;///сумма функций
245         break;
246     }
247     case 2:
248     {
249         f3=f1-f2;
250         break;
251     }
252     case 3:
253     {
254         f3=f1/f2;
255         break;
256     }
257     case 4:
258     {
259         f3=f1*f2;
260         break;
261     }
262 
263     default :
264     {
265         cout<<"NOOOOO";
266         break;
267     }
268     };
269     return 0;
270 }

Анастасия Бальцер

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

Пояснения к работе: В два текстовые файла занести количество точек и значения абсцисс и ординат функций, который написать в первом и втором пунктах меню, затем выбрать необходимую операцию и ввести имя файла, в который сохранятся полученные значения.

Скачать можно тут.


Белоусова Екатерина

Инструкция к программе: пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем пользователь выбирает одну из арифметических операций, которую он хочет применить к этим функциям. Создается третья функция. После пользователь вводит второй шаг для интерполяции. Третья функция интерполируется по новому шагу, а затем аппроксимируется.

Краткое описание алгоритма: в классе при помощи массива создаются две функции, с которыми потом работает программа. Эти функции перегружаются операторами арифметических операций, где затем полученная новая функция интерполируется и аппроксимируется.

Скачать программу можно по ссылке [2].

  1 #include <iostream>
  2 #include <locale.h>
  3 #include <math.h>
  4 #include <fstream>
  5 #include<iomanip>
  6 
  7 using namespace std;
  8 
  9 class functya ///создаем класс функции
 10 {
 11 
 12 private: ///объявляем тип переменных в привате
 13     double *mass, *mass1, *mass2; ///*mass, *mass1, *mass2 -определение двумерного массива
 14     double start, ending, step, step2, amountdouble; ///start-начало, ending-конец, step-шаг, amountdouble-количество точек (типа double)
 15 
 16 public: ///объявляем тип переменных в паблике
 17     int amount; ///amoun-количество точек (типа int)
 18 
 19 functya (double _start, double _ending, double _step):start(_start),ending(_ending),step(_step) ///создаем конструктор функции с объявлением переменных
 20 {
 21 
 22     amountdouble=((ending-start)/step)+1; ///подсчитываем количество точек с заданым шагом
 23     amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
 24 
 25 }
 26 
 27 void massiv1 () ///создаем функцию массива
 28 {
 29 
 30     mass=new double[amount]; ///создаем двумерный массив
 31     for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
 32     {
 33         mass[l]= pow((l*step+start),3); ///при помощи массива задаем функцию с которой будем работать
 34     }
 35     cout<< "\n";
 36 }
 37 
 38 void massiv2 () ///создаем функцию массива
 39 {
 40 
 41     mass=new double[amount]; ///создаем двумерный массив
 42     for (int l=0; l<amount; l++) ///создаем цикл от нуля до amount-количества точек
 43     {
 44         mass[l]= pow((l*step+start),2); ///при помощи массива задаем функцию с которой будем работать
 45     }
 46     cout<< "\n";
 47 
 48 }
 49 
 50 void interpol (double __start, double __ending, double __step) ///создаем функцию интерполяция с определением переменных
 51 {
 52 
 53     double amount1=((__ending-__start)/__step)+1; ///определяем тип и подсчитываем новое количество точек с новым шагом
 54     int amounti=static_cast<int>(amount1); ///преобразуем количество из типа double к типу int
 55 
 56     for (int i=0; i<amounti; i++) ///создаем цикл от 0 до amounti-нового количества точек
 57     {
 58 
 59         mass1=new double[amounti];
 60         double x = i*__step+__start; ///определяем тип и расчитываем координату Х
 61         double x0=(static_cast<int>((x-__start)/step)) * step+__start;///определяем тип и расчитываем координату х
 62                                                                       ///в интерполирующейся точке, которая стоит до новой точки
 63         double x1=x0+step;///определяем тип и расчитываем координату х1 прибавляя к предыдущей точке шаг
 64         int i0=(static_cast<int>((x-__start)/step));///определяем значение массива в i0 соответстующей значению функции в x0
 65         int i1=i0+1;
 66         mass1[i]=(((x - x0 )*(mass[i1] - mass[i0]))/( x1-x0)) + mass[i0];
 67         cout << "Х="<<i<<setw(10)<< "У= " << mass1[i] <<endl<<endl; ///выводим интерполяцию на экран
 68         ofstream fout("interpol.txt",ios::app);///сохраняем в файл
 69         fout<< "Х="<<i<<setw(10)<< "У="<<mass1[i]<<" \n";
 70         fout.close();
 71 
 72     }
 73 
 74     amount=amounti;
 75     delete []mass;
 76     mass = mass1;
 77 
 78 }
 79 
 80 void aprocsimation(double __start, double __ending, double __step) ///создаем функцию апроксимация с определением переменных
 81 {
 82 
 83     int N=amount; ///определяем тип и значение переменной N (равна количеству точек с заданным шагом)
 84     double SumXY=0; ///определяем тип и значение переменной SumXY ( сумма (Х*У) )
 85     double SumX=0; ///определяем тип и значение переменной SumX ( сумма Х )
 86     double SumY=0; ///определяем тип и значение переменной SumУ ( сумма У )
 87     double Sum_Xkv=0; ///определяем тип и значение переменной Sum_Xkv ( сумма (Х*Х) )
 88     double Xi; ///определяем тип переменной Xi
 89 
 90     mass1 = new double[N]; ///создаем двумерный массив
 91     for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
 92     {
 93 
 94         Xi=i*__step+__start; ///расчитываем Хi
 95         SumXY=SumXY+Xi*mass[i]; ///расчитываем SumXY
 96         SumX=SumX+Xi; ///расчитываем SumX
 97         SumY=SumY+mass[i]; ///расчитываем SumY
 98         Sum_Xkv=Sum_Xkv+Xi*Xi; ///расчитываем Sum_Xkv
 99 
100     }
101 
102     double a=(SumXY*N-SumX*SumY)/(N*Sum_Xkv-SumX*SumX); ///определяем тип и расчитываем коэффициент перед Х в уравнении аХ+b
103     double b=(SumY-a*SumX)/N; ///определяем тип и расчитываем свободный член в уравнении аХ+b
104 
105     if (b>0) ///если b положительное то
106     cout<<"Апроксимация: "<<a<<"*x+"<<b<<endl; ///выводим на экран: Апроксимация: а*Х+b
107 
108     else if (b<0) ///если b отрицательно то
109     cout<<"Апроксимация: "<<a<<"*x"<<b<<endl; ///выводим на экран: Апроксимация: а*Х b
110 
111     for (int i=0; i<N; i++) ///создаем цикл от 0 до N (количество точек с заданным шагом)
112     {
113         mass1[i] = a*(i*__step+__start)+b; ///при помощи массива создаем функцию подсчета точек при апроксимации
114     }
115 
116     delete[] mass;
117     mass=mass1;
118     vivod();///вывод на экран
119     zapis("aprocsimation.txt");///сохраненяем в файл
120 
121 }
122 
123 functya operator+ ( functya F) ///перегрузка оператора +
124 {
125 
126     functya tmp(start,ending,step);
127 
128     mass2=new double[amount];///создаем двумерный массив
129     for (int i=0; i<amount; i++)
130     {
131         mass2[i]=mass[i] + F.mass[i];///находим сумму двух функций
132     }
133     delete [] mass;
134     mass=mass2;
135     vivod();///выводим на экран результат
136     zapis("f3.txt");///сохраненяем в файл
137     cout<<"Введите шаг для интерполяции";
138     cin>>step2;
139     cout<<"Интерполяция: "<<"\n";
140     interpol(start,ending,step2);///вызов функции интерполяции
141     aprocsimation(start,ending,step2);///вызов функции аппроксимации
142     return tmp;
143 
144 }
145 
146 functya operator-( functya F)///перегрузка оператора -
147 {
148 
149     functya tmp(start,ending,step);
150 
151     mass2=new double[amount];///создаем двумерный массив
152     for (int i=0; i<amount; i++)
153     {
154         mass2[i]=mass[i] - F.mass[i];///находим разность двух функций
155     }
156 
157     delete [] mass;
158     mass=mass2;
159     vivod();///выводим на экран результат
160     zapis("f3.txt");///сохраненяем в файл
161     cout<<"Введите шаг для интерполяции";
162     cin>>step2;
163     cout<<"Интерполяция: "<<"\n";
164     interpol(start,ending,step2);///вызов функции интерполяции
165     aprocsimation(start,ending,step2);///вызов функции аппроксимации
166     return tmp;
167 
168 }
169 
170 functya operator*( functya F)///перегрузка оператора *
171 {
172     functya tmp(start,ending,step);
173 
174     mass2=new double[amount];///создаем двумерный массив
175     for (int i=0; i<amount; i++)
176     {
177         mass2[i]=mass[i] * F.mass[i];///находим произведение двух функций
178     }
179 
180     delete [] mass;
181     mass=mass2;
182     vivod();///выводим на экран результат
183     zapis("f3.txt");///сохраненяем в файл
184     cout<<"Введите шаг для интерполяции";
185     cin>>step2;
186     cout<<"Интерполяция: "<<"\n";
187     interpol(start,ending,step2);///вызов функции интерполяции
188     aprocsimation(start,ending,step2);///вызов функции аппроксимации
189     return tmp;
190 
191 }
192 
193 functya operator/( functya F)///перегрузка оператора /
194 {
195 
196     functya tmp(start,ending,step);
197 
198     mass2=new double[amount];///создаем двумерный массив
199     for (int i=0; i<amount; i++)
200     {
201         mass2[i]=mass[i] / F.mass[i];///находим частное двух функций
202     }
203 
204     delete [] mass;
205     mass=mass2;
206     vivod();///выводим на экран результат
207     zapis("f3.txt");///сохраненяем в файл
208     cout<<"Введите шаг для интерполяции ";
209     cin>>step2;
210     cout<<"Интерполяция: "<<"\n";
211     interpol(start,ending,step2);///интерполяция
212     aprocsimation(start,ending,step2);///вызов функции аппроксимации
213     return tmp;
214 
215 }
216 
217 void vivod ()///создаем функцию вывода на экран
218 {
219 
220     for (int l=0; l<amount; l++)
221     {
222         cout<<"Х"<<l<<setw(10)<< "Y= " << mass[l] <<"\n";
223     }
224 
225 }
226 
227 void zapis (char Zapis[])///созданем функцию записи в файл
228 {
229 
230     ofstream fout(Zapis);
231     for (int l=0; l<amount; l++)
232     {
233         fout<<"X="<<l<<setw(10)<<"Y="<<mass[l]<<" \n";
234     }
235 
236     fout.close();
237 
238 }
239 
240 };
241 
242 int main()
243 {
244 
245     setlocale(LC_ALL,"RUS");
246 
247     double start1, ending1, step1, step2;
248     int number;
249     cout<< "Введите начало отрезка ";
250     cin>> start1;
251     cout<< "Введите конец отрезка ";
252     cin>> ending1;
253     cout<<"Введите шаг для функций ";
254     cin>> step1;
255 
256     functya F1(start1,ending1,step1);///создаем первую функцию
257     F1.massiv1();
258     F1.vivod();///выводим координаты первой функции на экран
259     F1.zapis("F1.txt");///записываем координаты первой функции в файл
260 
261     cout<<"\n \n";
262 
263     functya F2(start1,ending1,step1);///создаем вторую функцию
264     F2.massiv2();
265     F2.vivod();///выводим координаты второй функции на экран
266     F2.zapis("F2.txt");///записываем координаты второй функции в файл
267 
268     cout<<"\n \n";
269 
270     functya F3(start1, ending1, step1);
271 
272     cout<<"Выберите, что вы хотите сделать с функциями: 1-найти сумму, 2-найти разность, 3-найти произведение, 4-найти частное ";
273     cin>>number;
274     cout<<"\n \n";
275 
276     if(number==1)
277     {
278         F3=F1+F2;
279     }
280 
281     else if (number==2)
282     {
283         F3=F1-F2;
284     }
285 
286     else if (number==3)
287     {
288         F3=F1*(F2);
289     }
290 
291     else if (number==4)
292     {
293         F3=F1/F2;
294     }
295 
296     else
297     {
298         cout<<"Ошибка ";
299     }
300 
301     return 0;
302 
303 }

Васильева Анастасия

Инструкция к программе:сначала в папке с программой создаются два файла input1 и input2, в которых на первой строчке число точек в функции, а потом в два столбика значения х и у (функции должны быть с одинаковым шагом). Пользователь поочередно выбирает действия: 1 - нужно будет написать имя файла, откуда считывать значения для первой функции (х и у), 2 - для второй функции, 3 - сложение функций, пишем название файла, куда будут записываться значения, 4 - разность, 5 - умножение, 6 - интерполяция функции с шагом 0,5 , получившейся в результате сложения двух начальных,(можно сделать интерполяцию функций, которые получились в результате разности или умножения, но нужно будет в коде в case 6: newf3.Inter(0.5).output() поменять индекс функции и новый шаг), 7 - аппроксимация функции, получившейся в результате сложения двух начальных,(можно сделать аппроксимацию функций, которые получились в результате разности или умножения, но нужно будет в коде в case 7: newf3.Approxy().output() поменять индекс функции), 8 - выход.

Краткое описание алгоритма: функции хранятся в программе как массив точек, заданных с определённым шагом по X на заданном отрезке. Вводить значения функции в программу можно считывая координаты точек из файла. Далее с любыми функциями можно производить следующие действия: сложение, вычитание, умножение, интерполяция и аппроксимация. При этом результат каждого из этих действий - новая функция. Результаты выводятся в файл. Скачать программу можно по ссылке [3].

Гильманов Илья

Описание программы: программа, с помощью которой можно складывать, умножать, вычитать, делить 2-е функции, аппроксимировать,интерполировать.

Суть программы: Программа позволяет задать 2 функции с любыми областями определения и любыми множествами значений, интерполировать их на любом шаге, аппроксимировать, а так же сложить 2 существующие функции. Программа написана в классе работы с функциями.

Инструкция к программе: 1. Пользователь вводит параметры первой функции 2. Пользователь вводит параметры второй функции 3. Происходит интерполяция первой функции по второй 4. Пользователь выбирает арифметическую операцию 5. При желании пользователь может выполнить аппроксимацию полученного результата

Скачать можно [здесь]

Демченко Артём

Описание программы: В программе создается две функции, которые мы можем просуммировать, интерполировать каждую из них и аппроксимировать каждую из них. После каждой операции ( кроме аппроксимации ) значения записываются в файл.

Инструкции: Запустите программу и выбором одного из трех параметров в меню выберете желаемую операцию. Далее следуйте указаниям из меню.


Скачать можно тут.

Иванова Яна

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

Инструкция к программе: Введите поочередно первый и последний элементы функций, а также их шаги. После этого введите число, соответствующее желаемому действию (соответствие указано в меню программы).

Посмотреть программу можно здесь

  1 #include <iostream>
  2 #include <fstream>
  3 #include <cstring>
  4 #include <stdlib.h>
  5 
  6 using namespace std;
  7 
  8 ofstream outfile;
  9 
 10 struct approx                                               //структура, необходимая для функции линейной интерполяции
 11 {
 12     double koefficientA, koefficientB;
 13 };
 14 
 15 struct dot                                                  //структура, содержащая в себе значения координат каждой точки
 16 {                                                           //по обеим осям
 17     double x, y;
 18 };
 19 
 20 struct polyana                                              //структура, содержащая номера первого и последнего элемента каждой
 21 {                                                           //функции и количество элементов каждой из них
 22     int a1, a2, b1, b2, k1, k2;
 23 };
 24 
 25 struct trees                                                //структура, содержащая номер элемента и логическое значение,
 26 {                                                           // отвечающее за нужность или не нужность интерполяции
 27     bool pol;                                               //при равенстве или неравенстве энных элементов двух функций
 28     int n;
 29 };
 30                                                             //непосредственно функция линейной интерполяции
 31 double pentagon (double x1, double x, double x2, double y1, double y2)
 32 {
 33     return (((x - x1)/(x2- x1))*(y2 - y1) + y1);
 34 }
 35 
 36 class stars                                                 //класс, позволяющий сохранять дискретные значения функции на
 37 {                                                           //определенном интервале с определенным шагом
 38     private:
 39 
 40         double a;                   //первое значение функции
 41         double b;                   //последнее значение функции
 42         double step;                //шаг
 43         int length;                 //длина
 44         int k;                      //счетчик количества элементов
 45 
 46     public:
 47 
 48         dot *massiv;
 49         stars (int _k)                                      //конструктор для создания объекта класса - структуры
 50         {                                                   //с двумя полями по количеству элементов
 51             massiv = new dot [_k];
 52             k = _k;
 53         }
 54         stars () {};                                        //конструктор
 55         stars (double _a, double _b, double _step)          //конструктор для создания объекта класса через начальный
 56                                                             //и коненый элементы с определенным шагом
 57         {
 58             a = _a;
 59             b = _b;
 60             step = _step;
 61 
 62             length = _b - _a + 1;
 63             k = 0;
 64 
 65             for (int i = _a ; i <= _b ; i += step)          //подсчет количества элементов функции
 66             {
 67                 k++;
 68             }
 69 
 70             massiv = new dot [k];                           //задание функции
 71             for (int i = 0 ; i < k ; i++)
 72                {
 73                     massiv[i].x = _a + _step * i;
 74                     massiv[i].y = i * 5;
 75                }
 76         }
 77 
 78         void outinfile ()                                   //вывод в файл значений функции
 79         {
 80             outfile.open ("meow", ios :: app);
 81 
 82             outfile << "x" << "          " << "y" << endl;
 83             for (int i = 0 ; i < k ; i++)
 84                 {
 85                     outfile << massiv[i].x << "        " << massiv[i].y << endl;
 86                 }
 87             outfile << endl;
 88             outfile.close();
 89         }
 90 
 91         void out ()                                         //вывод на экран значений функции
 92         {
 93             cout << "x" << "          " << "y" << endl;
 94             for (int i = 0 ; i < k ; i++)
 95                 {
 96                     cout << massiv[i].x << "        " << massiv[i].y << endl;
 97                 }
 98             cout << endl;
 99         }
100 
101         polyana prepare (stars &h)                          //подготовка совместной области определения для двух функций -
102         {                                                   //той части значений множества Х, на которой будут
103             trees del;                                      //производиться вычисления
104             polyana tmp;
105             if (massiv[0].x > h.massiv[0].x)                //поиск начала совместной области определения
106             {
107                 del = h.love(massiv[0].x);
108                 tmp.a2 = del.n + 1;
109                 tmp.a1 = 0;
110             }
111             else
112                 if (massiv[0].x < h.massiv[0].x)
113                 {
114                     del = love(h.massiv[0].x);
115                     tmp.a2 = 0;
116                     tmp.a1 = del.n + 1;
117                 }
118                 else
119                     if (massiv[0].x == h.massiv[0].x)
120                     {
121                         tmp.a1 = 0;
122                         tmp.a2 = 0;
123                     };
124 
125             if (massiv[k-1].x > h.massiv[k-1].x)            //поиск конца совместной области определения
126             {
127                 del = h.love(massiv[k-1].x);
128                 tmp.b2 = k-1;
129                 tmp.b1 = del.n;
130             }
131             else
132                 if (massiv[k-1].x < h.massiv[k-1].x)
133                 {
134                     del = h.love(massiv[k-1].x);
135                     tmp.b2 = del.n;
136                     tmp.b1 = k-1;
137                 }
138                 else
139                     if (massiv[k-1].x == h.massiv[k-1].x)
140                     {
141                         tmp.b2 = k-1;
142                         tmp.b1 = k-1;
143                     };
144 
145             tmp.k1 = 0;
146             for (int i = tmp.a1 ; i <= tmp.b1 ; i ++)       //подсчет количества элементов первой функции
147             {
148                 tmp.k1++;
149             }
150             tmp.k2 = 0;
151             for (int i = tmp.a2 ; i <= tmp.b2 ; i ++)       //подсчет количества элементов второй функции
152             {
153                 tmp.k2++;
154             }
155             return tmp;                                     //возвращает первые и последние значения обеих функций и
156         }                                                   //их количества элементов
157 
158     //ПЕРЕГРУЗКА ОПЕРАТОРОВ
159 
160     stars operator+ (stars & v)                             //сложение
161     {
162         polyana tmp = prepare(v);
163         int general = tmp.k1 + tmp.k2;                      //общее количество элементов обеих функций
164         stars F3(general);                                  //создание объекта класса только по количеству элементов
165         for (int i = 0 ; i < tmp.k1 ; i++)                  //заполнение первой части окончательного результата
166         {
167             F3.massiv[i].x = massiv[i+tmp.a1].x;
168             trees tiger = v.love(massiv[i+tmp.a1].x);
169             if (tiger.pol == true)                          //если значения по У в одной точке не совпадают, то интерполировать
170             {
171                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
172                                            F3.massiv[i].x,
173                                            v.massiv[tiger.n + 1].x,
174                                            v.massiv[tiger.n].y,
175                                            v.massiv[tiger.n + 1].y )
176                                            + massiv[i+tmp.a1].y;
177             }
178             else                                            //иначе, просто сложить значения
179             {
180                 F3.massiv[i].y = v.massiv[tiger.n].y + massiv[i+tmp.a1].y;
181             }
182 
183         }
184          {
185            for (int i = tmp.k1  ; i < (general) ; i++)      //заполнение второй части окончательного результата
186         {
187             F3.massiv[i].x = v.massiv[i + tmp.a2 - tmp.k1].x;
188             trees tiger = love(v.massiv[i + tmp.a2 - tmp.k1].x);
189             if (tiger.pol == true)
190             {
191                 F3.massiv[i].y = pentagon  (v.massiv[tiger.n].x,
192                                             F3.massiv[i].x,
193                                             v.massiv[tiger.n + 1].x,
194                                             v.massiv[tiger.n].y,
195                                             v.massiv[tiger.n + 1].y )
196                                             + v.massiv[i+tmp.a1 - tmp.k1].y;
197             }
198             else
199                 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
200         }
201 
202         for (int i = 0; i < (general); i++)                  //сортировка
203         {
204             for (int j = 0; j < (general - 1); j ++)
205             {
206                 dot temp;
207                 if (F3.massiv[j].x > F3.massiv[j + 1].x)
208                 {
209                     temp = F3.massiv[j];
210                     F3.massiv[j] = F3.massiv[j + 1];
211                     F3.massiv[j + 1] = temp;
212                 }
213                 else                                        //если элементы совпадают, то нужно выбросить один из них
214                 if (F3.massiv[j].x == F3.massiv[j + 1].x)
215                 {
216                     int l = j;
217                     while (l < general)
218                     {
219                         F3.massiv[l].x = F3.massiv[l + 1].x;
220                         F3.massiv[l].y = F3.massiv[l + 1].y;
221                         l++;
222                     }
223                     general--;
224                 }
225             }
226         }
227 
228 
229         stars normalny (general);                           //создание элемента класса по длине
230         for (int i = 0; i < (general); i++)
231         {
232             normalny.massiv[i].x = F3.massiv[i].x;
233             normalny.massiv[i].y = F3.massiv[i].y;
234         }
235         a = normalny.massiv[0].x;
236         b = normalny.massiv[general].x;
237         return normalny;
238     }
239     };
240 
241         stars operator* (stars & v)                         //умножение
242     {
243         polyana tmp = prepare(v);
244         int general = tmp.k1 + tmp.k2;
245         stars F3(tmp.k1 + tmp.k2);
246         for (int i = 0 ; i < tmp.k1 ; i++)
247         {
248             F3.massiv[i].x = massiv[i+tmp.a1].x;
249             trees tiger = v.love(massiv[i+tmp.a1].x);
250             if (tiger.pol == true)
251             {
252                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,       F3.massiv[i].x,
253                                            v.massiv[tiger.n + 1].x,   v.massiv[tiger.n].y,
254                                            v.massiv[tiger.n + 1].y )* (massiv[i+tmp.a1].y);
255             }
256             else
257             {
258                 F3.massiv[i].y = v.massiv[tiger.n].y * massiv[i+tmp.a1].y;
259             }
260 
261         }
262         {
263             for (int i = tmp.k1 ; i < (general) ; i++)
264         {
265             F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
266             trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
267             if (tiger.pol == true)
268             {
269                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
270                                             F3.massiv[i].x,
271                                             v.massiv[tiger.n + 1].x,
272                                             v.massiv[tiger.n].y,
273                                             v.massiv[tiger.n + 1].y )
274                                             + v.massiv[i+tmp.a1 - tmp.k1].y;
275             }
276             else
277                 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
278         }
279 
280         for (int i= 0; i < (general); i++)
281         {
282             for (int j = 0; j < (general - 1); j ++)
283             {
284                 dot temp;
285                 if (F3.massiv[j].x > F3.massiv[j+1].x)
286                 {
287                     temp = F3.massiv[j];
288                     F3.massiv[j] = F3.massiv[j+1];
289                     F3.massiv[j+1] = temp;
290                 }
291                 else
292                 if (F3.massiv[j].x == F3.massiv[j+1].x)
293                 {
294                     int l = j;
295                     while (l < general)
296                     {
297                         F3.massiv[j].x = F3.massiv[j+1].x;
298                         l++;
299                     }
300                     general--;
301                 }
302             }
303         }
304 
305          for (int i = 0 ; i < general ; i++)
306         {
307 
308             cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
309         }
310 
311 
312         stars normalny(general);
313         for (int i = 0; i < (general); i++)
314         {
315             normalny.massiv[i].x = F3.massiv[i].x;
316             normalny.massiv[i].y = F3.massiv[i].y;
317         }
318         a = normalny.massiv[0].x;
319         b = normalny.massiv[general].x;
320         return normalny;
321     }
322     };
323 
324     stars operator- (stars & v)                             //вычитание
325     {
326         polyana tmp = prepare(v);
327         int general = tmp.k1 + tmp.k2;
328         stars F3(tmp.k1 + tmp.k2);
329         for (int i = 0 ; i < tmp.k1 ; i++)
330         {
331             F3.massiv[i].x = massiv[i+tmp.a1].x;
332             trees tiger = v.love(massiv[i+tmp.a1].x);
333             if (tiger.pol == true)
334             {
335                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,       F3.massiv[i].x,
336                                            v.massiv[tiger.n + 1].x,   v.massiv[tiger.n].y,
337                                            v.massiv[tiger.n + 1].y )- massiv[i+tmp.a1].y;
338             }
339             else
340             {
341                 F3.massiv[i].y = v.massiv[tiger.n].y - massiv[i+tmp.a1].y;
342             }
343 
344         }
345         {
346             for (int i = tmp.k1 ; i < (general) ; i++)
347         {
348             F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
349             trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
350             if (tiger.pol == true)
351             {
352                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
353                                             F3.massiv[i].x,
354                                             v.massiv[tiger.n + 1].x,
355                                             v.massiv[tiger.n].y,
356                                             v.massiv[tiger.n + 1].y )
357                                             + v.massiv[i+tmp.a1 - tmp.k1].y;
358             }
359             else
360                 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
361         }
362 
363         for (int i= 0; i < (general); i++)
364         {
365             for (int j = 0; j < (general - 1); j ++)
366             {
367                 dot temp;
368                 if (F3.massiv[j].x > F3.massiv[j+1].x)
369                 {
370                     temp = F3.massiv[j];
371                     F3.massiv[j] = F3.massiv[j+1];
372                     F3.massiv[j+1] = temp;
373                 }
374                 else
375                 if (F3.massiv[j].x == F3.massiv[j+1].x)
376                 {
377                     int l = j;
378                     while (l < general)
379                     {
380                         F3.massiv[j].x = F3.massiv[j+1].x;
381                         l++;
382                     }
383                     general--;
384                 }
385             }
386         }
387 
388          for (int i = 0 ; i < general ; i++)
389         {
390 
391             cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
392         }
393 
394 
395         stars normalny(general);
396         for (int i = 0; i < (general); i++)
397         {
398             normalny.massiv[i].x = F3.massiv[i].x;
399             normalny.massiv[i].y = F3.massiv[i].y;
400         }
401         a = normalny.massiv[0].x;
402         b = normalny.massiv[general].x;
403         return normalny;
404     }
405     };
406 
407     stars operator/ (stars & v)                             //деление
408     {
409         polyana tmp = prepare(v);
410         int general = tmp.k1 + tmp.k2;
411         stars F3(tmp.k1 + tmp.k2);
412         for (int i = 0 ; i < tmp.k1 ; i++)
413         {
414             F3.massiv[i].x = massiv[i+tmp.a1].x;
415             trees tiger = v.love(massiv[i+tmp.a1].x);
416             if (tiger.pol == true)
417             {
418                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,       F3.massiv[i].x,
419                                            v.massiv[tiger.n + 1].x,   v.massiv[tiger.n].y,
420                                            v.massiv[tiger.n + 1].y )/ (massiv[i+tmp.a1].y);
421             }
422             else
423             {
424                 F3.massiv[i].y = (v.massiv[tiger.n].y) / (massiv[i+tmp.a1].y);
425             }
426 
427         }
428          {
429             for (int i = tmp.k1 ; i < (general) ; i++)
430         {
431             F3.massiv[i].x = v.massiv[i+tmp.a2 - tmp.k1].x;
432             trees tiger = love(v.massiv[i+tmp.a2 - tmp.k1].x);
433             if (tiger.pol == true)
434             {
435                 F3.massiv[i].y = pentagon (v.massiv[tiger.n].x,
436                                             F3.massiv[i].x,
437                                             v.massiv[tiger.n + 1].x,
438                                             v.massiv[tiger.n].y,
439                                             v.massiv[tiger.n + 1].y )
440                                             + v.massiv[i+tmp.a1 - tmp.k1].y;
441             }
442             else
443                 F3.massiv[i].y = massiv[tiger.n].y + v.massiv[i+tmp.a2 - tmp.k1].y;
444         }
445 
446         for (int i= 0; i < (general); i++)
447         {
448             for (int j = 0; j < (general - 1); j ++)
449             {
450                 dot temp;
451                 if (F3.massiv[j].x > F3.massiv[j+1].x)
452                 {
453                     temp = F3.massiv[j];
454                     F3.massiv[j] = F3.massiv[j+1];
455                     F3.massiv[j+1] = temp;
456                 }
457                 else
458                 if (F3.massiv[j].x == F3.massiv[j+1].x)
459                 {
460                     int l = j;
461                     while (l < general)
462                     {
463                         F3.massiv[j].x = F3.massiv[j+1].x;
464                         l++;
465                     }
466                     general--;
467                 }
468             }
469         }
470 
471          for (int i = 0 ; i < general ; i++)
472         {
473 
474             cout <<F3.massiv[i].x<< ' ' << F3.massiv[i].y <<endl;
475         }
476 
477 
478         stars normalny(general);
479         for (int i = 0; i < (general); i++)
480         {
481             normalny.massiv[i].x = F3.massiv[i].x;
482             normalny.massiv[i].y = F3.massiv[i].y;
483         }
484         a = normalny.massiv[0].x;
485         b = normalny.massiv[general].x;
486         return normalny;
487     }
488     };
489 
490     trees love (double a)                                   //
491     {
492         trees privet;
493         for (int i = 0; i < k; i++ )
494             if ((massiv[i].x < a)&& (a < massiv[i+1].x))
495             {
496                 privet.n = i;
497                 privet.pol = true;
498                 return privet;
499             }
500             else
501                 if (massiv[i].x == a)
502                 {
503                     privet.n = i;
504                     privet.pol = false;
505                     return privet;
506                 }
507                 else
508                 if (massiv[i+1].x == a)
509                 {
510                     privet.n = i+1;
511                     privet.pol = false;
512                     return privet;
513                 }
514     }
515 
516 
517     approx approximate ()                                   //функция аппроксимации
518     {
519         approx hey;
520         stars mattafix (double a, double b, double step, int k, int length);
521         double sigmaX = 0;
522         double sigmaY = 0;
523         double sigmaXY = 0;
524         double sigmaXsqrt = 0;
525         for (int i = 0; i < length; i++)
526         {
527            sigmaX += a + step * i;
528            sigmaY += b + i * 5;
529            sigmaXY += (a + step * i)*(b + i * 5);
530            sigmaXsqrt += (a + step * i)*(a + step * i);
531         }
532         hey.koefficientA = ((k * (sigmaXY) - (sigmaX*sigmaY))/(k*sigmaXsqrt - (sigmaX * sigmaX)));
533         hey.koefficientB = ((sigmaY - hey.koefficientA*sigmaX)/k);
534         return hey;
535 
536 
537     }
538 };
539 
540 int main()
541 {
542     int tyu;
543     stars function3;
544     int firstnumber1;
545     int firstnumber2;
546     int lastnumber1;
547     int lastnumber2;
548     int step1;
549     int step2;
550     while (true)
551     {
552 
553         cout << "Input 0 - vvedite parametry pervoy funkcii"<< endl;
554         cout << "Input 1 - vvedite parametry vtoroy funkcii"<< endl;
555         cout << "Input 2 - slozhenie"<< endl;
556         cout << "Input 3 - umnozhenie"<< endl;
557         cout << "Input 4 - delenie"<< endl;
558         cout << "Input 5 - vychitanie"<< endl;
559         cout << "Input 6 - aproximate"<< endl;
560         cin >> tyu ;
561 
562         switch (tyu)
563         {
564             case 0:
565             {   cout << "Vvedite pervy x" << endl;
566                 cin >> firstnumber1;
567                 cout << "Vvedite posledniy x" << endl;
568                 cin >> lastnumber1;
569                 cout << "Vvedite shag" << endl;
570                 cin >> step1;
571                 break;
572             }
573             case 1:
574             {
575                 cout << "Vvedite pervy x" << endl;
576                 cin >> firstnumber2;
577                 cout << "Vvedite posledniy x" << endl;
578                 cin >> lastnumber2;
579                 cout << "Vvedite shag" << endl;
580                 cin >> step2;
581                 break;
582             }
583             case 2:
584             {
585                 stars function1 (firstnumber1, lastnumber1, step1);
586                 function1.out();
587                 function1.outinfile ();
588 
589                 stars function2 (firstnumber2, lastnumber2, step2);
590                 function2.out();
591                 function2.outinfile ();
592 
593                 function3 = function1 + function2;
594                 function3.out();
595                 function3.outinfile ();
596                 break;
597             }
598             case 3:
599             {
600                 stars function1 (firstnumber1, lastnumber1, step1);
601                 function1.out();
602                 function1.outinfile ();
603 
604                 stars function2 (firstnumber2, lastnumber2, step2);
605                 function2.out();
606                 function2.outinfile ();
607 
608                 function3 = function1 * function2;
609                 function3.out();
610                 function3.outinfile ();
611                 break;
612             }
613             case 4:
614             {
615                 stars function1 (firstnumber1, lastnumber1, step1);
616                 function1.out();
617                 function1.outinfile ();
618 
619                 stars function2 (firstnumber2, lastnumber2, step2);
620                 function2.out();
621                 function2.outinfile ();
622 
623                 function3 = function1 / function2;
624                 function3.out();
625                 function3.outinfile ();
626                 break;
627             }
628             case 5:
629             {
630 
631                 stars function1 (firstnumber1, lastnumber1, step1);
632                 function1.out();
633                 function1.outinfile ();
634 
635                 stars function2 (firstnumber2, lastnumber2, step2);
636                 function2.out();
637                 function2.outinfile ();
638 
639                 function3 = function1 - function2;
640                 function3.out();
641                 function3.outinfile ();
642                 break;
643             }
644             case 6:
645                 {
646                     approx you;
647                     function3.approximate();
648                     outfile.open ("meow", ios :: app);
649                     outfile << "Y = "<< you.koefficientA <<"* x + "<<you.koefficientB << endl;
650                     outfile << endl;
651                     outfile.close();
652 
653 
654                 }
655             }
656         }
657     };

Капитанюк Светлана

Описание программы:: программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции. функции хранятся в программе как массив точек, заданных с определенным шагом по X на заданном отрезке. Функции заданы автоматически, поэтому нет необходимости вводить каждый промежуток, нужно ввести только начало, конец и шаг. Далее пользователю на выбор будет представлено несколько операций с функциями, такие как: сложение, вычитание, умножение и деление функции одну на другую. Если функции имеют различный шаг, топеред этимони интерполируются. Так же в программе предусмотрена аппроксимация.


Скачать можно тут.

Киселёв Лев Описание программы:программа позволяет интерполировать и аппроксимировать значения функции, а также складывать две функции, используя перегрузку.

Скачать можно [здесь]

Козловская Анна

Описание программы: программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.

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


Скачать можно тут.

Лебедев Станислав

Описание программы: программа позволяет сложить, умножить, возвести одну в степень другой две таблично заданные функции, а также линейно аппроксимировать результат. Чтение и вывод происходит через файл.

Пояснения к алгоритму:

  1. Прочитанные из файла функции нужно отсортировать.
  2. Найти совместную область определения, то есть, найти множество пересечения областей определения функций, над которыми совершается операция.
  3. Создать третью функцию, со следующими свойствами : область определения состоит только из точек, принадлежащих совместной области определения, каждая точка области значений является результатом нужной операции над точкой области значений одной из функций и, либо интерполированной точкой по другой функции, либо, если есть возможность, точным значением из ее области значений.

Скачать можно тут.


  1 #include <iostream>
  2 #include <math.h>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <malloc.h>
  6 #include <fstream>
  7 
  8 using namespace std;
  9 
 10 double base(double x)                                        //базовая функция ( если задавать через шаг и начальный х
 11 {
 12     return x;
 13 }
 14 
 15 struct ap                                                   //две одинаковые структуры это нехорошо,коненчо,но зато наглядно...
 16 {
 17     double k,b;
 18 };
 19 
 20 struct fun                                                   //один столбик в таблице функции
 21 {
 22     double x,y;
 23 };
 24 
 25 struct sf                                                   //структура нужная, для возражеия значений из функции "prepare" класса F
 26 {
 27     int i1,i2,e1,e2;
 28     double glength, gfirstx, glastx;
 29 };
 30 
 31 double intr(double x1,double x2,double x,double y1,double y2)  // линенейная интерполяция
 32 {
 33     return ( ((x-x1)/(x2-x1)) * (y2-y1) + y1 );
 34 }
 35 
 36 ap aproks(fun b [],int n)                                       //линейная аппроксимация
 37 {
 38     ap r;
 39     double xy = 0,x = 0,y = 0,sqx = 0,xsq = 0;
 40     for (int i = 0; i < n; i++)                                 //вычисление коэффицентов
 41     {
 42         xy  += b[i].x*b[i].y;
 43         x   += b[i].x;
 44         y   += b[i].y;
 45         sqx += b[i].x*b[i].x;
 46         xsq += b[i].x;
 47     }
 48     xsq *= xsq;
 49 
 50     r.k = (n*xy - x*y)/(n*sqx - xsq);                       //использование формул
 51     r.b = (y - r.k*x)/n;
 52     return r;
 53 }
 54 
 55 class F
 56 {
 57 private:
 58     int length;
 59     double firstx, step, lastx;
 60     fun *a;
 61 public:
 62     F(){}
 63     F(int l,double f,double s)                              //конструктор, создающий фунцию по длине,первоиу элементу,шагу по х, y вычисляется по базовой функции
 64     {
 65         if (l >= 0)
 66           a = new fun [l];
 67         firstx = f;
 68         length = l;
 69         step = s;
 70         lastx = firstx+(length - 1)*step;
 71 
 72 
 73         for (int i = 0;i < length; i ++)
 74         {
 75             a[i].y = base(firstx + i*step);
 76             a[i].x = firstx + i*step;
 77         }
 78 
 79     }
 80 
 81     F (fun b[],int l)                                   //конструктор для создания фунции с уже известными областями определния и значений
 82     {
 83         length = l;
 84         a = new fun [l];
 85         for (int i = 0; i < l;i++)
 86             a[i] = b[i];
 87 
 88         for (int i = 0; i < l;i++)
 89             for (int j = 0; j < (l - 1); j++)
 90                 if (a[j].x > a[j + 1].x)
 91                 {
 92                     fun tmp = a[j];
 93                     a[j] = a[j + 1];
 94                     a[j + 1] = a[j];
 95                 }
 96 
 97         firstx = a[0].x;
 98         lastx = a[length - 1].x;
 99     }
100 
101     void addpar (double k, double b, int l, fun z[] )                           //позволяет создать и заполнить переданным массивом поле объекта класса
102     {
103         a = new fun [l];
104         for (int i = 0; i < l; i++)
105         {
106             a[i].y = k*z[i].x + b;
107             a[i].x = z[i].x;
108         }
109         length = l;
110     }
111 
112     double getelx(int i)                                //возращает значение из поля "х" iого элемента
113     {
114         return a[i].x;
115     }
116 
117 
118     double getely(int i)                               //возращает значение из поля "х" iого элемента
119     {
120         return a[i].y;
121     }
122 
123     int getlength()                                 //возращает размер области определения функции(в точках)
124     {
125         return length;
126     }
127 
128     void FOut()                                     //выводит функцию на экран
129     {
130       cout << "   x         y" << endl;
131       for (int i = 0;i < length; i ++)
132           cout << "   " << a[i].x << "         " << a[i].y << endl;
133       cout << endl;
134     }
135 
136 
137     int pfind(double x)const                        //возращает либо номер элемента,идущщий перед элементом, большим,чем х; в случае нахождения равного, возращает число, противоположное номеру следующего элемента(иначе может вернуться нуль,а нуль знака не имееет)
138     {
139         for (int i = 0; i < length-1; i++ )
140         {
141             if (((a[i].x < x) && (a[i + 1].x > x)))
142                 return (i + 1);
143             else
144                 // чтобы иметь возможность проанализировать полученное значение функции,мы должны понимать, было найденно равное или промежуточное значение. "флагом" равных значений является знак минус,но так у нуля нет знака,то приходиться все сдвигать на 1
145                 if (a[i].x == x)
146                   return -(i + 1);
147                 else
148                     if (a[i + 1].x == x)
149                         return -(i + 2);
150         }
151 //        cerr << "fail!!" << endl;
152         return -1;
153     }
154 
155     sf prepare(F &x)const                                      //"подготовка" функций к бинарной операции (нахождение совместной области определения
156     {
157         sf r;
158         if (a[0].x > x.a[0].x)
159         {
160             r.gfirstx = a[0].x;
161             r.i1 = 0;
162             r.i1 = 0;
163             double k = x.pfind(a[0].x);
164             if (k < 0)
165                 r.i2 = -k - 1;
166             else
167                 r.i2 = (k - 1) + 1;
168         }
169         else
170         {
171             r.gfirstx = x.a[0].x;
172             double k = pfind(x.a[0].x);
173             if (k < 0)
174                 r.i1 = -k - 1;
175             else
176                 r.i1 = (k - 1) + 1;
177             r.i2 = 0;
178         }
179 
180         if (a[length - 1].x < x.a[x.length - 1].x)
181         {
182             r.glastx = a[length - 1].x;
183             r.e1 = length - 1;
184             double k = x.pfind(r.glastx);
185             if (k < 0)
186                 r.e2 = -k - 1;
187             else
188                 r.e2 = (k - 1) - 1;
189         }
190         else
191         {
192             r.glastx = x.a[x.length - 1].x;
193             double k = pfind(r.glastx);
194             if (k < 0)
195                 r.e1 = -k - 1;
196             else
197                 r.e1 = (k - 1) + 1;
198             r.e2 = x.length - 1;
199         }
200         r.glength = length + x.length - r.i1 - (length - (r.e1 + 1)) - r.i2 - (x.length - (r.e2 + 1));
201 
202         return r;
203     }
204 
205     void ad (fun b[],int l)                                  //присвоить массиву объекта класса F значения массива b
206     {
207         length = l;
208         a = new fun [l];
209         for (int i = 0; i < l;i++)
210             a[i] = b[i];
211         firstx = a[0].x;
212         lastx = a[length - 1].x;
213     }
214 
215     fun *geta()                                         //получения указателя на начало массива в поле класса
216     {
217         return a;
218     }
219 
220     F operator +(F &x) const                               //сложение двух функций
221     {
222         int i1, e1, i2, e2, kk = 0;
223         double gfirstx, glastx, glength;
224 
225         if (((x.lastx < firstx) && (x.firstx < firstx)) || ((lastx < x.firstx) && (firstx < x.firstx)))
226         {
227             cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
228             F fl(-1,0,0);
229             return fl;
230         }
231         sf r = prepare(x);
232         F tmp(r.glength,r.gfirstx,r.glastx);
233         for (int i = 0; i <= (r.e1 - r.i1); i++)
234         {
235             tmp.a[i].x = a[i + r.i1].x;            //поправка,введенная таким образом,чтобы номер,с которого начинается отсчет был первым в новой области определения
236             int ii = x.pfind(tmp.a[i].x);
237             if (ii < 0)
238                 tmp.a[i].y = x.a[-ii - 1].y + a[i + r.i1].y;
239             else
240                 tmp.a[i].y = intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y) + a[i + r.i1].y;
241         }
242         for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
243         {
244             int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
245             if (ii >= 0)
246             {
247                 tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
248                 tmp.a[i - kk].y = intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y) + x.a[i - (r.e1 - r.i1 + 1) + r.i2].y;
249             }
250             else
251             {
252                 kk++;
253                 glength --;
254                 tmp.length --;
255             }
256         }
257 
258         for (int i = 0; i < glength; i++)
259             for (int j = 0; j < glength - 1; j++)
260             if (tmp.a[j].x > tmp.a[j + 1].x)
261             {
262                 fun t = tmp.a[j];
263                 tmp.a[j] = tmp.a[j + 1];
264                 tmp.a[j + 1] = t;
265             }
266 
267         return tmp;
268 }
269 
270     F operator *(F & x) const                                         //умножение двух функций
271     {
272         int i1, e1, i2, e2, kk = 0;
273         double gfirstx, glastx, glength;
274 
275         if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
276         {
277             cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
278             F fl(-1,0,0);
279             return fl;
280         }
281 
282         sf r = prepare(x);
283         F tmp(r.glength,r.gfirstx,r.glastx);
284 
285         for (int i = 0; i <= (r.e1 - r.i1); i++)
286         {
287             tmp.a[i].x = a[i + r.i1].x;
288             int ii = x.pfind(tmp.a[i].x);
289             if (ii < 0)
290                 tmp.a[i].y = x.a[-ii - 1].y * a[i + r.i1].y;
291             else
292                 tmp.a[i].y = intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y) * a[i + r.i1].y;
293         }
294         for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
295         {
296             int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
297             if (ii >= 0)
298             {
299                 tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
300                 tmp.a[i - kk].y = intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y) * x.a[i - (r.e1 - r.i1 + 1) + r.i2].y;
301             }
302             else
303             {
304                 kk++;
305                 glength --;
306                 tmp.length --;
307             }
308         }
309 
310         for (int i = 0; i < glength; i++)
311             for (int j = 0; j < glength - 1; j++)
312             if (tmp.a[j].x > tmp.a[j + 1].x)
313             {
314                 fun t = tmp.a[j];
315                 tmp.a[j] = tmp.a[j + 1];
316                 tmp.a[j + 1] = t;
317             }
318 
319         return tmp;
320     }
321 
322     F operator ^(F & x) const                                  //возведение функции слева от оператора в степень функции справа от оператора
323     {
324         int i1, e1, i2, e2, kk = 0;
325         double gfirstx, glastx, glength;
326 
327         if (((x.lastx < firstx) && (x.firstx < firstx)) || ((x.firstx < lastx) && (firstx < x.firstx)))
328         {
329             cout << "Nevozmozhno, prover'te oblasti opredelenia" << endl;
330             F fl(-1,0,0);
331             return fl;
332         }
333 
334         sf r = prepare(x);
335         F tmp(r.glength,r.gfirstx,r.glastx);
336 
337         for (int i = 0; i <= (r.e1 - r.i1); i++)
338         {
339             tmp.a[i].x = a[i + r.i1].x;
340             int ii = x.pfind(tmp.a[i].x);
341             if (ii < 0)
342                 tmp.a[i].y = pow(x.a[-ii - 1].y, a[i + r.i1].y);
343             else
344                 tmp.a[i].y = pow(intr(x.a[ii - 1].x , x.a[ii + 1].x , tmp.a[i].x , x.a[ii].y , x.a[ii + 1].y), a[i + r.i1].y);
345         }
346         for (int i = (r.e1 - r.i1 + 1); i <= (r.e2 - r.i2 + (r.e1 - r.i1) + 1) ; i++)
347         {
348             int ii = pfind(x.a[i - (r.e1 - r.i1 + 1) + r.i2].x);
349             if (ii >= 0)
350             {
351                 tmp.a[i - kk].x = x.a[i - (r.e1 - r.i1 + 1) + r.i2].x;
352                 tmp.a[i - kk].y = pow(intr (a[ii - 1].x , a[(ii - 1) + 1].x , tmp.a[i - kk].x , a[ii - 1].y, a[(ii - 1) + 1].y), x.a[i - (r.e1 - r.i1 + 1) + r.i2].y);
353             }
354             else
355             {
356                 kk++;
357                 glength --;
358                 tmp.length --;
359             }
360         }
361 
362         for (int i = 0; i < glength; i++)
363             for (int j = 0; j < glength - 1; j++)
364             if (tmp.a[j].x > tmp.a[j + 1].x)
365             {
366                 fun t = tmp.a[j];
367                 tmp.a[j] = tmp.a[j + 1];
368                 tmp.a[j + 1] = t;
369             }
370 
371         return tmp;
372     }
373 };
374 
375 int main()
376 {
377    /*
378     F f1(5,-2,1.5);
379     F f2(30,-10,0.5);
380     F f3, f4;
381     f1.FOut();
382     f2.FOut();
383     f3 = f1 + f2;
384     f3.FOut();
385     f4 = f1 * f2;
386     f4.FOut();
387     cout << " ________" << endl;
388 */
389     char vc, s[255], ce;
390     ifstream infile;
391     int n;
392     fun *a;
393     F f5,f6,f7,f8,f9;
394 
395     while(true)
396     {
397     start :
398         system("cls");
399         cout << "1 - Vvesti 1uu func"            << endl;
400         cout << "2 - Vvesti 2uu func"            << endl;
401         cout << "3 - Sloshit'"                   << endl;
402         cout << "4 - Umnozhit'"                  << endl;
403         cout << "5 - Vozvesti v stepen'"         << endl;
404         cout << "6 - Aproximirovat'"             << endl;
405         cout << "7 - Zapics' v file func"        << endl;
406         cout << "8 - Zapics' v file aprok fun"   << endl;
407         cout << "0 - Vihod"                      << endl;
408         cin  >> vc;
409         switch (vc)
410         {
411             case '0':
412                 return 0 ;
413             case '1':
414                 {
415                 system("cls");
416                 strcpy(s,"");
417                 delete []a;
418                 a = NULL;
419                 cout << "Vvedite imya fila" << endl;
420                 cin >> s;
421                 strcat(s, ".txt");
422                 infile.open(s);
423                 infile >> n;
424                 a = new fun [n];
425                 for(int i = 0; i < n; i ++)
426                     infile >> a[i].x >> a[i].y;
427                 f5.ad(a,n);
428                 f5.FOut();
429                 infile.close();
430                 cout << "Nazhmite \"b\" chotibi viti" << endl;
431                 cin >> ce;
432                 while (true)
433                 if (ce == 'b')
434                     goto start;
435                 }
436             case '2':
437                 {
438                 system("cls");
439                 strcpy(s,"");
440                 delete []a;
441                 a = NULL;
442                 cout << "Vvedite imya fila" << endl;
443                 cin >> s;
444                 strcat(s, ".txt");
445                 infile.open(s);
446                 infile >> n;
447                 a = new fun[n];
448                 for(int i = 0; i < n; i ++)
449                     infile >> a[i].x >> a[i].y;
450                 f6.ad(a,n);
451                 f6.FOut();
452                 infile.close();
453                 cout << "Nazhmite \"b\" chotibi viti" << endl;
454                 cin >> ce;
455                 while (true)
456                 if (ce == 'b')
457                     goto start;
458                 }
459             case '3':
460                 system("cls");
461                 f5.FOut();
462                 f6.FOut();
463                 f7 = f5 + f6;
464                 f7.FOut();
465                 cout << "Nazhmite \"b\" chotibi viti" << endl;
466                 cin >> ce;
467                 while (true)
468                 if (ce == 'b')
469                     goto start;
470             case '4':
471                 system("cls");
472                 f5.FOut();
473                 f6.FOut();
474                 f7 = f5 * f6;
475                 f7.FOut();
476                 cout << "Nazhmite \"b\" chotibi viti" << endl;
477                 cin >> ce;
478                 while (true)
479                 if (ce == 'b')
480                     goto start;
481             case '5':
482                 system("cls");
483                 f5.FOut();
484                 f6.FOut();
485                 f7 = f5 ^ f6;
486                 f7 = f5 ^ f6;
487                 f7.FOut();
488                 cout << "Nazhmite \"b\" chotibi viti" << endl;
489                 cin >> ce;
490                 while (true)
491                 if (ce == 'b')
492                     goto start;
493             case '6':
494             {
495                 system("cls");
496                 ap tmp = aproks(f7.geta(), f7.getlength());
497                 f8.addpar(tmp.k, tmp.b, f7.getlength(), f7.geta());
498                 f8.FOut();
499                 cout << "Nazhmite \"b\" chotibi viti" << endl;
500                 cin >> ce;
501                 while (true)
502                 if (ce == 'b')
503                     goto start;
504             }
505             case '7':
506             {
507                 system("cls");
508                 strcpy(s,"");
509                 cout << "Vvedite imya fila" << endl;
510                 cin >> s;
511                 strcat(s, ".txt");
512                 ofstream outfile(s);
513                 outfile << "x           y" << endl;
514                 for (int i = 0; i < f7.getlength(); i ++)
515                     outfile << f7.getelx(i) << "           " << f7.getely(i) << endl;
516 
517                 cout << "done" << endl;
518                 cout << "Nazhmite \"b\" chotibi viti" << endl;
519                 cin >> ce;
520                 while (true)
521                 if (ce == 'b')
522                     goto start;
523             }
524             case '8':
525                 system("cls");
526                 strcpy(s,"");
527                 cout << "Vvedite imya fila" << endl;
528                 cin >> s;
529                 strcat(s, ".txt");
530                 ofstream outfile(s);
531                 outfile << "x           y" << endl;
532                 for (int i = 0; i < f8.getlength(); i ++)
533                     outfile << f8.getelx(i) << "           " << f8.getely(i) << endl;
534                 cout << "done" << endl;
535                 cout << "Nazhmite \"b\" chotibi viti" << endl;
536                 cin >> ce;
537                 while (true)
538                 if (ce == 'b')
539                     goto start;
540         }
541     }
542     return 0;
543 }

Лобанов Илья

Описание программы: Программа позволяет складывать , вычитать , делить,умножать 2 функции,заданные на одном интервале.При считывании с файла сначала указывается отрезок, потом величина шага, а потом дискретные значения.

Скачать можно [тут]


Лосева Татьяна

Краткое описание алгоритма : Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.

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

Cкачать программу можно здесь

  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 #define N 5//количество точек
  6 
  7 const double l1 = 5;//задаём начальный шаг функций
  8 const double l2 = 0.7;//шаг для интерполяции
  9 
 10 class Func 
 11 {//класс,хранящий функцию,содержащий методы:печать,перегрузка,интерполяция,апроксимация
 12 
 13 public:
 14 	Func(int size) : size_(size), ax(new double[size]), by(new double[size])//создаём два массива,заполняем нулями
 15 	{
 16 		for (int i = 0; i< size_; i++)
 17 		{
 18 			ax[i] = 0;
 19 			by[i] = 0;   //все элементы обоих массивов обнуляются
 20 		}
 21 	}
 22 
 23 	void print()//вывод на экран
 24 	{
 25 		cout << "x: ";
 26 		for (int i = 0; i < size_; i++)
 27 			cout << ax[i] << " ";
 28 		cout << endl << "y: ";
 29 		for (int i = 0; i < size_; i++)
 30 			cout << by[i] << " ";
 31 		cout << endl;
 32 	}
 33 
 34 	Func &operator+(Func &f2)//функция перегрузки:cложение функций
 35 	{
 36 		Func *result = new Func(size_);//создаём результирующую функцию,равную сумме двух f2 и this
 37 		for (int i = 0; i < size_; i++)
 38 		{
 39 			result->ax[i] = this->ax[i];//суммируем координаты X
 40 			result->by[i] = f2.by[i] + this->by[i];//суммируем координаты Y
 41 		}
 42 		cout << "Sum f(x)=f1+f2:" << endl;//выводим на экран сумму функций
 43 		result->print();
 44 		return *result;
 45 	}
 46 
 47 	void Int(double L) //метод Интерполяции
 48 	{
 49 		int M = (this->ax[this->size_ - 1] - this->ax[0]) / L + 1; //M- количество элементов массива с координатами интерполирующей функции;
 50 		Func result = Func(M);//cоздаём функцию,в кторой будет храниться результат интерполяции
 51 		cout << "M =" << M << endl;//выводим M для проверки 
 52 		cout << "Interpolation: " << endl;
 53 		int t;
 54 		for (int i = 1; i < M; i++)
 55 		{
 56 			result.ax[0] = this->ax[0];
 57 			result.ax[i] = result.ax[i - 1] + L;//интерполируем Х,прибавляя шаг к каждому предыдущему элементу 
 58 			t = (result.ax[i - 1] - result.ax[0]) / l1;//считаем номер элемента,"левого" от искомого
 59 
 60                        //интерполируем Y по формуле
 61 			result.by[i] = this->by[t] + ((result.ax[i] - this->ax[t]) / (this->ax[t + 1] - this->ax[t]))*(this->by[t + 1] - this->by[t]);
 62 
 63 		}
 64 
 65 		result.print();//выводим результат
 66 	}
 67 
 68 	void aprox()//Апроксимация
 69 	{
 70 		double a=0;
 71           for(int i=0;i<size_;i++)//считаем сумму x
 72 		   a=this->ax[i]+a;
 73          
 74 
 75 			double b=0;
 76 			for(int i=0;i<size_;i++)//считаем сумму y
 77 				b=this->by[i]+b;
 78 			
 79 
 80 			double c=0;
 81 			for(int i=0;i<size_;i++)//считаем сумму квадратов x
 82 				c=(this->ax[i])*(this->ax[i])+c;
 83 			
 84 
 85 			double d=0;
 86 			for(int i=0;i<size_;i++)//считаем сумму xy
 87 				d=(this->ax[i])*(this->by[i])+d;
 88 			
 89 
 90 			//затем решаем систему для у=kx+m
 91 			//(1)c*k+a*m=d
 92 			//(2)a*k+size_*m=b;
 93 			//k=(d-am)/с
 94 			//подставим в (2)
 95 			double m;
 96 			m=(b*c-a*d)/(c*size_-a*a);
 97 			double k;
 98 			k=(d-a*m)/c;
 99 			cout<<"aproximacia :: ";
100 			cout<<"y="<<k<<"x+"<<m<<endl;
101 
102 	}
103 
104 
105 	double *ax;
106 	double *by;
107 
108 private:
109 	int size_;//размер массива
110 };
111 
112 
113 
114 
115 class Cord//класс,создающий и хранящий значение функций
116 {
117 public:
118 	Cord(double x0, double s) :x0(x0), s(s)//x0-начальная координата;s-шаг
119 	{
120 	}
121 
122 	void Fyx1(Func func)//метод,считающий координаты нашей функции y=x
123 	{
124 		int i;
125 		func.ax[0] = x0;
126 		for (i = 1; i < N; i++)//считаются иксы
127 		{
128 			func.ax[i] = x0 + s;
129 			x0 = func.ax[i];
130 		}
131 		for (i = 0; i<N; i++)
132 			func.by[i] = func.ax[i];//считаем координаты у
133 		cout << "f1 :" << endl;
134 		func.print();
135 		cout << endl;
136 	}
137 
138 	void Fyx2(Func func)//метод,считающий координаты нашей функции y=x+1
139 	{
140 		int i;
141 		func.ax[0] = x0;
142 		for (i = 1; i<N; i++)//считаем иксы
143 		{
144 			func.ax[i] = x0 + s;
145 			x0 = func.ax[i];
146 		}
147 		for (i = 0; i<N; i++)
148 			func.by[i] = func.ax[i] + 1;//считаем игрики
149 		cout << "f2 :" << endl;
150 		func.print();
151 		cout << endl;
152 	}
153 
154 private:
155 	double x0;//начальная координата
156 	double s;//шаг
157 };
158 
159 int main()
160 {
161 	Func f1(N);//создание функции f1
162 	Func f2(N);//создание f2
163 	Cord s1(0, l1);//cоздаём объект s1
164 	Cord s2(0, l1);//cоздаём объект s2
165 	s1.Fyx1(f1);//задаём координаты 1ой функции
166 	s2.Fyx2(f2);//задаём координаты 2ой функции
167 
168       //сложение функций:
169 	
170 	Func f3 = f2 + f1;//есть тоже ,что и Func f3 = f2.operator+(f1);
171 
172 	f1.Int(l2);//Интерполируем f1 с новым шагом l2
173 	f1.aprox();//Апроксимируем f1
174 	
175 	getchar();
176 	return 0;
177 }

Сергей Ляжков Описание программы:программа позволяет проводить следующие действия с функциями: сложение, вычитание, умножение, те же действия с числами, проводить аппроксимацию и интерполяцию Скачать можно [тут]


Нарядчиков Александр
Инструкция: Пользователю достаточно просто запустить программу.
Описание программы: В окне рисуются графики с разным шагом, количеством точек, начальными и конечными координатами, по клавише 'G' происходит их кубическая интерполяция, также рисуется график их суммы. По клавише 'S' можно сохранить полученный график в текстовый документ в виде координат его точек. По клавише 'L' можно загрузить график из текстового документа, и он появится в окне программы. Также происходит линейная аппроксимация графика суммы, и график аппроксимации рисуется на экран.
Описание алгоритма: Вся графика написана с помощью библиотек OpenGL и GLUT. Кубическая интерполяция написана с помощью кривых Безье(интерполяция по четырем точкам - кубическая кривая). При сложение двух графиков происходит их интерполяция, для приведения их к общему шагу. Линейная аппроксимация написана с помощью метода наименьших квадратов.

"T05GRAPH.CPP"

  1 /* FILENAME: T05GRAPH.CPP
  2  * LAST UPDATE: 17.01.2016
  3  */
  4 
  5 #include "GRAPH.H"
  6 
  7 /* Глобальные переменные */
  8 // Глобальная переменная, хранящая время в секундах с момента старта программы
  9 double SyncTime;
 10 // Глобальные переменные для отслеживания нажатия клавиш
 11 bool IsGraph, IsSave, IsLoad, IsLoaded;
 12 
 13 /* Timer function */
 14 // Подсчет времени
 15 void Timer( void )
 16 {
 17 	long t;
 18 	static long StartTime = -1;
 19 
 20 	t = clock();
 21 	if (StartTime == -1)
 22 		StartTime = t;
 23 	SyncTime = (double)(t - StartTime) / CLOCKS_PER_SEC;
 24 } /* End of 'Timer' function */
 25 
 26 /* Display function */
 27 // Стандартная функция, вызываемая при перерисовке окна
 28 void Display( void )
 29 {
 30 	graph G1(-15, 15, 0.1), G2(2, 10, 0.4), G3, G4;
 31 
 32 	// Запуск времени
 33 	Timer();
 34 
 35 	// Установка цвета закраски фона в белый
 36 	glClearColor(1, 1, 1, 1);
 37 	// Очищаем цветовой буфер для создания нового изображения
 38 	glClear(GL_COLOR_BUFFER_BIT);
 39 
 40 	glLoadIdentity();
 41 	glScaled(0.1 / (1366 / 768.0), 0.1, 0.1);
 42 
 43 	// Отрисовка осей X и Y
 44 	glBegin(GL_LINE_STRIP);
 45 
 46 	glColor3d(0, 0, 1);
 47 	glVertex2d(0, -1000);
 48 	glVertex2d(0, 1000);
 49 
 50 	glColor3d(1, 0, 0);
 51 	glVertex2d(-1000, 0);
 52 	glVertex2d(1000, 0);
 53 
 54 	glEnd();
 55 
 56 	/* Отрисовка графиков */
 57 	// Отрисовка первого графика и его интерполяция по клавише "G"
 58 	G1.Draw(sin);
 59 	if (IsGraph == 1)
 60 		G1.Interpolation_Draw(1.0 / 32);
 61 
 62 	// Отрисовка второго графика и его интерполяция по клавише "G"
 63 	G2.Draw(log);
 64 	if (IsGraph == 1)
 65 		G2.Interpolation_Draw(1.0 / 32);
 66 
 67 	// Отрисовка графика суммы для первого и второго графиков
 68 	G3 = G2 + G1;
 69 	glColor3d(0, 1, 0);
 70 	G3.Draw();
 71 	// Аппроксимация графика суммы
 72 	G3.Approximation();
 73 
 74 	// Сохранение графика по клавише "S"
 75 	if (IsSave == 1)
 76 	{
 77 		G3.SaveArray();
 78 		IsSave == 0;
 79 	}
 80 	
 81 	// Загрузка графика по клавише "L"
 82 	if (IsLoad == 1)
 83 	{
 84 		delete[] G4.mas;
 85 		delete[] G4.Color;
 86 		G4.LoadArray("graph.txt");
 87 		IsLoad == 0;
 88 		IsLoaded = 1;
 89 	}
 90 	
 91 	// Отрисовка загруженного графика
 92 	if (IsLoaded == 1)
 93 	{
 94 		glColor3d(1, 0, 0);
 95 		G4.Draw();
 96 		IsLoaded = 0;
 97 	}
 98 
 99 	// Чистка памяти
100 	delete[] G1.mas;
101 	delete[] G1.Color;
102 	delete[] G2.mas;
103 	delete[] G2.Color;
104 	delete[] G3.mas;
105 	delete[] G3.Color;
106 	delete[] G4.mas;
107 	delete[] G4.Color;
108 
109 	glFinish();
110 	// Копируем вторичный буфер в окно
111 	glutSwapBuffers();
112 	// Вызываем функцию обновления кадра
113 	glutPostRedisplay();
114 } /* End of 'Display' function */
115 
116 /* Keyboard function */
117 // Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
118 void Keyboard( unsigned char Key, int X, int Y )
119 {
120 	// Выход из программы
121 	if (Key == 27)
122 		exit(0);
123 	// Отрисовка интерполированных графиков
124 	else if ((Key == 'G') || (Key == 'g'))
125 		IsGraph = !IsGraph;
126 	// Сохранение графика суммы в файл
127 	else if ((Key == 'S') || (Key == 's'))
128 		IsSave = !IsSave;
129 	// Загрузка графика из файла
130 	else if ((Key == 'L') || (Key == 'l'))
131 		IsLoad = !IsLoad;
132 	// Открытие программы в полном экране
133 	else if ((Key == 'F') || (Key == 'f'))
134 		glutFullScreen();
135 } /* End of 'Keyboard' function */
136 
137 /* Main function */
138 int main( int argc, char *argv[] )
139 {
140 	// Инициализации OpenGL и GLUT
141 	glutInit(&argc, argv);
142 	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
143 
144 	// Задача размеров и позиции окна
145 	glutInitWindowPosition(0, 0);
146 	glutInitWindowSize(500, 500);
147 	// Создание окна
148 	glutCreateWindow("T05GRAPH");
149 
150 	// Установка функций 'обратного вызова'
151 	glutDisplayFunc(Display);
152 	glutKeyboardFunc(Keyboard);
153 
154 	// Запускаем основной цикл построения
155 	glutMainLoop();
156 	return 0;
157 } /* End of 'main' function */
158 
159 /* END OF 'T05GRAPH.CPP' FILE */

"GRAPH.CPP"

  1 /* FILENAME: GRAPH.CPP
  2  * LAST UPDATE: 17.01.2016
  3  */
  4 
  5 #include "GRAPH.H"
  6 
  7 /* Load Array of points function */
  8 // Загрузка графика из файла по точкам
  9 void graph::LoadArray( char *FileName )
 10 {
 11 	// Создание указателя на тип FILE
 12 	FILE *F;
 13 
 14 	// Создание файла и открытие его в режиме чтения
 15 	fopen_s(&F, FileName, "rt");
 16 
 17 	// Количество точек
 18 	fscanf(F, "%d", &N);
 19 	// Шаг функции
 20 	fscanf(F, "%lf", &Step);
 21 	// Начальная координата по X
 22 	fscanf(F, "%lf", &MinX);
 23 	// Конечная координата по X
 24 	fscanf(F, "%lf", &MaxX);
 25 	
 26 	// Выделение памяти под массив точек
 27 	mas = new vec[N];
 28 
 29 	// Заполнение массива точек из файла
 30 	for (int i = 0; i < N; ++i)
 31 	{
 32 		// Заполнение по X
 33 		fscanf(F, "%lf", &mas[i].X);
 34 		// Заполнение по Y
 35 		fscanf(F, "%lf", &mas[i].Y);
 36 	}
 37 
 38 	// Закрытие файла
 39 	fclose(F);
 40 } /* End of 'LoadArray' function */
 41 
 42 /* Fill mas function */
 43 // Заполнение массива координат точек с цветом
 44 void graph::Fill( double(*f)(double) )
 45 {
 46 	// Выделение памяти под массив точек
 47 	mas = new vec[N];
 48 	// Выделение памяти под массив цветов
 49 	Color = new vec[N];
 50 
 51 	// Заполнение массивов
 52 	for (int i = 0; i < N; i++)
 53 	{
 54 		mas[i] = vec(MinX + i * Step, f(MinX + i * Step));
 55 		Color[i] = vec::Rnd();
 56 	}
 57 } /* End of 'Fill' function */
 58 
 59 /* Draw graph function */
 60 // Рисование заполненного графика на экран
 61 void graph::Draw( void )
 62 {
 63   // Задача размер точки
 64 	glPointSize(1);
 65 	// Рисование
 66 	glBegin(GL_POINTS);
 67 	for (int i = 0; i < N; i++)
 68  		glVertex2d(mas[i].X, mas[i].Y);
 69 	glEnd();
 70 } /* End of 'Draw' function */
 71 
 72 /* Draw graph function */
 73 // Рисование не заполненного еще графика на экран
 74 void graph::Draw( double(*f)(double) )
 75 {
 76 	// Заполнение массива
 77 	graph::Fill(f);
 78 
 79 	// Задача цвета и размера точки
 80 	glColor3d(0, 0, 0);
 81 	glPointSize(1);
 82 	// Рисование
 83 	glBegin(GL_POINTS);
 84 	for (int i = 0; i < N; i++)
 85 		glVertex2d(mas[i].X, mas[i].Y);
 86 	glEnd();
 87 } /* End of 'Draw' function */
 88 
 89 /* Interpolation draw graph function */
 90 // Рисование интерполированного графика на экран
 91 void graph::Interpolation_Draw( double i_step )
 92 {
 93 	// Коэффициент Катмулл-Рома
 94 	double alpha = 1.0 / 6;
 95 	
 96 	// Кубическая интерполяция кривыми Безье
 97 	for (int i = 0; i < N - 1; i++)
 98 	{
 99 		// Создание 4 точек для интерполяции по ним
100 		vec P0 = mas[i], P1, P2, P3 = mas[i + 1];
101 		vec Color0 = mas[i], Color1, Color2, Color3 = mas[i + 1];
102 
103 		// Значения для первого и последнего отрезков
104 		if (i == 0)
105 		{
106 			P1 = (mas[1] - mas[0]) * alpha + mas[0];
107 			Color1 = (mas[1] - mas[0]) * alpha + mas[0];
108 		}
109 		else
110 		{
111 			P1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
112 			Color1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
113 		}
114 		if (i == N - 2)
115 		{
116 			P2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
117 			Color2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
118 		}
119 		else
120 		{
121 			P2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
122 			Color2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
123 		}
124 
125 		glLineWidth(2);
126 		glBegin(GL_LINE_STRIP);
127 		for (double t = 0; t <= 1; t += i_step)
128 		{
129 			vec p, color;
130 
131 			// Вычисление точки интерполированного графика по 4 точкам
132 			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;
133 			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;
134 
135 			// Рисование
136 			glColor3d(color.X / 10, 0, color.Y);
137 			glVertex2d(p.X, p.Y);
138 		}
139 		glEnd();
140 	}
141 } /* End of 'Interpolation_Draw' function */
142 
143 /* Interpolation graph function */
144 // Интерполяция графика
145 graph graph::Interpolation( double i_step )
146 {
147 	graph G_New;
148 	// Коэффициент Катмулл-Рома
149 	double alpha = 1.0 / 6;
150 
151 	// Заполнение параметров для нового графика
152 	G_New.MinX = MinX;
153 	G_New.MaxX = MaxX;
154 	G_New.Step = Step * i_step;
155 	G_New.N = (int)((G_New.MaxX - G_New.MinX) / G_New.Step);
156 	G_New.mas = new vec[G_New.N];
157 	
158 	// Кубическая интерполяция кривыми Безье
159 	for (int i = 0; i < N - 1; i++)
160 	{
161 		// Создание 4 точек для интерполяции по ним
162 		vec P0 = mas[i], P1, P2, P3 = mas[i + 1];
163 	
164 		// Значения для первого и последнего отрезков
165 		if (i == 0)
166 			P1 = (mas[1] - mas[0]) * alpha + mas[0];
167 		else
168 			P1 = (mas[i + 1] - mas[i - 1]) * alpha + mas[i];
169 		if (i == N - 2)
170 			P2 = -(mas[N - 1] - mas[N - 2]) * alpha + mas[N - 1];
171 		else
172 			P2 = -(mas[i + 2] - mas[i]) * alpha + mas[i + 1];
173 	
174 		for (double t = 0; t <= 1; t += i_step)
175 		{
176 			vec p;
177 
178 			// Вычисление точки интерполированного графика по 4 точкам
179 			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;
180 		}
181 	}
182 
183 	return G_New;
184 } /* End of 'Interpolation' function */
185 
186 /* Sum of 2 graphics function */
187 // Сложение двух графиков
188 graph graph::operator+( graph &G )
189 {
190 	graph G_New, G1, G2;
191 	int i, j;
192 
193 	// Заполнение параметров графика суммы
194 	G_New.MinX = (MinX >= G.MinX) ? MinX : G.MinX;
195 	G_New.MaxX = (MaxX <= G.MaxX) ? MaxX : G.MaxX;
196 	G_New.Step = Step * G.Step;
197 	G_New.N = (int)((G_New.MaxX - G_New.MinX) / G_New.Step);
198 	G_New.mas = new vec[G_New.N];
199 
200 	// Интерполяция слагаемых графиков, для приведение к общему шагу
201 	G1 = Interpolation(G.Step);
202 	G2 = G.Interpolation(Step);
203 
204 	// Поиск общего начала и конца графиков
205 	for (i = 0; i < G1.N; i++)
206 		if (fabs(G1.mas[i].X - G_New.MinX) <= Threshold)
207 			break;
208 
209 	for (j = 0; j < G2.N; j++)
210 		if (fabs(G2.mas[j].X - G_New.MinX) <= Threshold)
211 			break;
212 
213 	// Заполнение графика суммы
214 	for (int k = 0; k < G_New.N; k++)
215 	{
216 		G_New.mas[k].X = G_New.MinX + k * G_New.Step;
217 		G_New.mas[k].Y = G1.mas[i + k].Y + G2.mas[j + k].Y;
218 	}
219 
220 	return G_New;
221 } /* End of 'Sum' function */
222 
223 /* Save Array of points function */
224 // Сохранение графика в файл по точкам
225 void graph::SaveArray( void )
226 {
227 	// Создание указателя на тип FILE
228 	FILE *F;
229 
230 	// Создание файла и открытие его в режиме записи
231 	fopen_s(&F, "graph.txt", "wt");
232 
233 	/* Запись в файл данных */
234 	// Количество точек
235 	fprintf(F, "%d\n", N);
236 	// Шаг функции
237 	fprintf(F, "%lf\n", Step);
238 	// Начальная координата по X
239 	fprintf(F, "%lf\n", MinX);
240 	// Конечная координата по X
241 	fprintf(F, "%lf\n", MaxX);
242 
243 	// Координаты всех точек
244 	for (int i = 0; i < N; ++i)
245 	  fprintf(F, "%lf %lf ", mas[i].X, mas[i].Y);
246 
247 	// Закрытие файла
248 	fclose(F);
249 } /* End of 'SaveArray' function */
250 
251 /* Approximation of function function */
252 // Аппроксимация графика
253 void graph::Approximation( void )
254 {
255 	double k, b, s1 = 0, s2 = 0, s3 = 0, s4 = 0;
256 
257 	// Линейная аппроксимация
258 	for (int i = 0; i < N; i++)
259 	{
260 		if (fabs(mas[i].X) < MAX && fabs(mas[i].Y) < MAX)
261 		{
262 			s1 += mas[i].X * mas[i].Y;
263 			s2 += mas[i].X;
264 			s3 += mas[i].X * mas[i].X;
265 			s4 += mas[i].Y;
266 		}
267 	}
268 
269 	k = (N * s1 - s2 * s4) / (double(N) * s3 - s2 * s2);
270 	b = (s4 - k * s2) / double(N);
271 
272 	// Задача цвета и ширины линии
273 	glColor3d(1, 0.5, 0);
274 	glLineWidth(1);
275 	// Рисование
276 	glBegin(GL_LINE_STRIP);
277 	glVertex2d(MinX, MinX * k + b);
278 	glVertex2d(MaxX, MaxX * k + b);
279 	glEnd();
280 } /* End of 'Approximation' function */
281 
282 /* End of 'GRAPH.CPP' file */

"GRAPH.H"

  1 /* FILENAME: GRAPH.H
  2  * LAST UPDATE: 17.01.2016
  3  */
  4 
  5 #ifndef _GRAPH_H_
  6 #define _GRAPH_H_
  7 
  8 #define _CRT_SECURE_NO_WARNINGS
  9 
 10 #include <iostream>
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <math.h>
 14 #include <time.h>
 15 #include <GL\glut.h>
 16 
 17 #define MAX 100
 18 
 19 using namespace std;
 20 
 21 /* Useful constants */
 22 const double Threshold = 1e-10;
 23 const double Infinity = 1e+10;
 24 
 25 /* Vector representation type */
 26 class vec
 27 {
 28 public:
 29 	double X, Y;
 30 
 31 	/* Default constructor */
 32 	vec( void )
 33 	{
 34 	}
 35 
 36 	/* Class constructor */
 37 	vec( double A ) : X(A), Y(A)
 38 	{
 39 	}
 40 
 41 	/* Class constructor */
 42 	vec( double A, double B ) : X(A), Y(B)
 43 	{
 44 	}
 45 
 46 	static double R0( void )
 47 	{
 48 		return rand() / (double)RAND_MAX;
 49 	} /* End of 'R0' function */
 50 
 51 	static vec Rnd( void )
 52 	{
 53 		return vec(R0(), R0());
 54 	} /* End of 'Rnd' function */
 55 
 56 	/* The functions of operations on vectors */
 57 
 58 	/* Vector = vector function */
 59 	vec operator=( vec &B )
 60 	{
 61 		X = B.X;
 62 		Y = B.Y;
 63 
 64 		return B;
 65 	} /* end of 'operator+' function */
 66 
 67 	/* Vector add vector function */
 68 	vec operator+( const vec &B ) const
 69 	{
 70 		return vec(X + B.X, Y + B.Y);
 71 	} /* end of 'operator+' function */
 72 
 73 	/* Vector sub vector function */
 74 	vec operator-( const vec &B ) const
 75 	{
 76 		return vec(X - B.X, Y - B.Y);
 77 	} /* end of 'operator-' function */
 78 
 79 	vec operator-( void ) const
 80 	{
 81 		return vec(-X, -Y);
 82 	} /* end of 'operator-' function */
 83 
 84 	/* Vector mul number function */
 85 	vec operator*( const double N ) const
 86 	{
 87 		return vec(X * N, Y * N);
 88 	} /* end of 'operator*' function */
 89 
 90 	/* Vector div number function */
 91 	vec operator/( const double N ) const
 92 	{
 93 		return vec(X / N, Y / N);
 94 	} /* end of 'operator/' function */
 95 
 96 	/* Vector dot vector function */
 97 	double operator&( const vec &B ) const
 98 	{
 99 		return double(X * B.X + Y * B.Y);
100 	} /* end of 'operator&' function */
101 
102 	vec & operator+=( const vec &B )
103 	{
104 		X += B.X;
105 		Y += B.Y;
106 
107 		return *this;
108 	} /* end of 'operator+=' function */
109 
110 	vec & operator-=( const vec &B )
111 	{
112 		X -= B.X;
113 		Y -= B.Y;
114 
115 		return *this;
116 	} /* end of 'operator-=' function */
117 
118 	vec & operator*=( const double N )
119 	{
120 		X *= N;
121 		Y *= N;
122 
123 		return *this;
124 	} /* end of 'operator*=' function */
125 
126 	vec & operator/=( const double N )
127 	{
128 		X /= N;
129 		Y /= N;
130 
131 		return *this;
132 	} /* end of 'operator/=' function */
133 
134 	double operator!( void ) const
135 	{
136 		return double(X * X + Y * Y);
137 	} /* end of 'operator!' function */
138 
139 	/* Access vector components by index function */
140 	double operator[]( const int i ) const
141 	{
142 		switch (i)
143 		{
144 		case 0:
145 			return double(X);
146 		case 1:
147 			return double(Y);
148 		}
149 	} /* end of 'operator[]' function */
150 
151 	/* Normalizing vector function */
152 	vec & Normalize( void )
153 	{
154 		double len = !*this;
155 
156 		if (len != 1 && len != 0)
157 			*this /= sqrt(len);
158 		return *this;
159 	} /* end of 'Normalize' function */
160 }; /* end of 'vec' class */
161 
162 /* Graph class */
163 class graph
164 {
165 public:
166 	double MinX, MaxX, Step; // Начальная координата по X; Конечная координата по X; Шаг функции
167 	int N; // Количество точек
168 	vec *mas, *Color; // Массивы точек и цветов
169 
170 	/* Default constructor */
171 	graph( void )
172 	{
173 		MinX = -10, MaxX = 10, Step = 0.1, N = 200;
174 	}
175 
176 	/* Class constructor */
177 	graph( double _MinX, double _MaxX, double _Step ) : MinX(_MinX), MaxX(_MaxX), Step(_Step)
178 	{
179 		N = (int)((MaxX - MinX) / Step);
180 		// Выделение памяти
181 		mas = new vec[N];
182 		Color = new vec[N];
183 	}
184 
185 	/* Load Array of points function */
186 	void LoadArray( char *FileName );
187 
188 	/* Fill mas function */
189 	void Fill( double(*f)(double) );
190 
191 	/* Draw graph function */
192 	void Draw( double(*f)(double) );
193 
194 	/* Draw graph function */
195 	void Draw( void );
196 
197 	/* Interpolation draw graph function */
198 	void Interpolation_Draw( double i_step );
199 
200 	/* Interpolation graph function */
201 	graph Interpolation( double i_step );
202 
203 	/* Sum of 2 graphics function */
204 	graph operator+( graph &G );
205 
206 	/* Save Array of points function */
207 	void SaveArray( void );
208 
209 	/* Approximation of function function */
210 	void Approximation( void );
211 }; /* end of 'graph' class */
212 
213 #endif /* _GRAPH_H_ */
214 
215 /* End of 'GRAPH.H' file */

Скачать архив

Рубинова Раиса

Описание программы: программа, позволяющая складывать, вычитать, умножать и делить две функции, заданные на одном интервале, интерполирующая первую функцию по второй и аппроксимирующая результат арифметической операции с заданными пользователем функции.

Инструкция к программе: 1. Пользователь вводит параметры первой функции 2. Пользователь вводит параметры второй функции (при этом шаг второй функции меньше шага первой) 3. Происходит интерполяция первой функции по второй 4. Пользователь выбирает арифметическую операцию 5. При желании пользователь может выполнить аппроксимацию полученного результата


Скачать можно тут.


  1 #ifndef FUNC_H
  2 #define FUNC_H
  3 
  4 
  5 class Func
  6 {
  7     public:
  8         Func(double a1, double b1, double c1);
  9         virtual ~Func();
 10         void DefFunc ();    // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
 11         void PluFunc (Func D);  // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
 12         void operator +(Func D); // перегрузка оператора '+'
 13         void MinFunc (Func D);  // функция, линейно вычитающая значения второй функции из значений первой функции
 14         void operator -(Func D); // перегрузка оператора '-'
 15         void UmnFunc (Func D);  // функция, линейно переумножающая значения функций
 16         void operator *(Func D);  // перегрузка оператора '*'
 17         void DelFunc (Func D);  // функция, линейно делящая значения первой функци на значения второй функции
 18         void operator /(Func D);  // перегрузка оператора '/'
 19         void In (Func D);   // функция, интерполирующая первую функцию по второй
 20         void App (); // функция, аппроксимирующая полученную в результате сложения/вычитания/деления/умножения двух функций функцию
 21         void Viv ();  // Функция вывода на экран значений
 22     protected:
 23     private:
 24         double a,b,c;
 25         int j,z;
 26         double *A,*B;
 27 };
 28 
 29 #endif // FUNC_H
 30 
 31 
 32 
 33 #include "Func.h"
 34 #include <fstream>
 35 #include <iostream>
 36 #include <math.h>
 37 
 38 Func::Func(double a1, double b1, double c1):a(a1),b(b1),c(c1)   // конструктор для класса Func, создающий объект данного класса, определенный тремя значениями, введенными пользователем
 39 {
 40     double d=(b-a)/c;   // расчет количества элементов, определяющих функцию
 41     j=floor(d);    // созданной целочисленной переменной присваивается значение, равное целой части числа, рассчитанного выше, с округлением в меньшую сторону
 42     A = new double [j+1];   // создание массива
 43 }
 44 
 45 Func::~Func()   // деструктор для класса Func
 46 {
 47     //dtor
 48 }
 49 
 50 void Func::Viv ()   // Функция вывода на экран значений
 51 {
 52     std::cout << "x ";
 53     for (int z=0; z<=j; ++z)
 54     {
 55         std::cout << z+1 << " ";
 56     }
 57 }
 58 
 59 void Func::DefFunc ()   // функция, определяющая количество элементов j на промежутке от a до b, с шагом c
 60 {
 61     double x;   // создание переменной, используемой для расчета значений функции
 62     for(int i=0; i<=j; ++i) // создание цикла, рассчитывающего j элементов
 63     {
 64         x =i*c+a;   // задание значения перемнной x, определенной выше
 65         A[i]=x*x;   // задание значения самой функции (при этом в данной ситуации нам неважно, как именно задается функция, ее значения могут быть определены любым способом, от этого алгоритм не меняется)
 66         std::cerr << A[i] << " ";   // вывод на экран значения функции
 67     }
 68 }
 69 
 70 void Func::PluFunc (Func D)   // функция, складывающая значения двух функций линейно (то есть значения первой функции при определенной переменной x складывается со значением второй функции при том же значении переменной)
 71 {
 72     std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
 73     for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
 74     {
 75         B[i]=B[i]+D.A[i];   // сложение значений двух функций для одного и того же значения переменной
 76     }
 77     for (int i=0; i<=D.j; ++i) // создание цикла, рассчитанного на то же количество раз, что и предыдущий
 78     {
 79         out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
 80     }
 81     out.close();    // закрытие файла после записи в него значений
 82     D.Viv();
 83     std::cout << std::endl << "y ";
 84     for (int i=0; i<=D.j; ++i)  // аналогичный предыдущему цикл, выводящий значения на экран
 85     {
 86         std::cout << B[i] << " ";
 87     }
 88 }
 89 void Func::operator +(Func D)   // перегрузка оператора '+'
 90 {
 91     PluFunc(D);                         // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1+f2 будет работать аналогично записи f1.PluFunc(f2)
 92 }
 93 void Func::MinFunc (Func D)    // функция, линейно вычитающая значения второй функции из значений первой функции
 94 {
 95     std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
 96     for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
 97     {
 98         B[i]=B[i]-D.A[i];   // вычитание значений второй функций из значений первой для одного и того же значения переменной
 99     }
100     for (int i=0; i<=D.j; ++i)  // создание цикла, рассчитанного на то же количество раз, что и предыдущий
101     {
102         out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
103     }
104     out.close();    // закрытие файла после записи в него значений
105     D.Viv();
106     std::cout << std::endl << "y ";
107     for (int i=0; i<=D.j; ++i)  // аналогичный предыдущему цикл, выводящий значения на экран
108     {
109         std::cout << B[i] << " ";
110     }
111 }
112 void Func::operator -(Func D)   // перегрузка оператора '-'
113 {
114     MinFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1-f2 будет работать аналогично записи f1.MinFunc(f2)
115 }
116 void Func::UmnFunc (Func D)     // функция, линейно переумножающая значения функций
117 {
118     std::ofstream out("zap.txt");    // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
119     for(int i=0; i<=D.j; ++i)   // создание цикла, повторяющегося (D.j+1) раз
120     {
121         B[i]=B[i]*D.A[i];   // умножение значений первой функций на значенийя второй для одного и того же значения переменной
122     }
123     for (int i=0; i<=D.j; ++i)     // создание цикла, рассчитанного на то же количество раз, что и предыдущий
124     {
125         out << B[i] << '\n';    // запись значений, полученных в предыдущем цикле, в файл
126     }
127     out.close();    // закрытие файла после записи в него значений
128     D.Viv();
129     std::cout << std::endl << "y ";
130     for (int i=0; i<=D.j; ++i)   // аналогичный предыдущему цикл, выводящий значения на экран
131     {
132         std::cout << B[i] << " ";
133     }
134 }
135 void Func::operator *(Func D)   // перегрузка оператора '*'
136 {
137     UmnFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1*f2 будет работать аналогично записи f1.UmnFunc(f2)
138 }
139 void Func::DelFunc (Func D)    // функция, линейно делящая значения первой функци на значения второй функции
140 {
141     std::ofstream out("zap.txt");   // открытие файла "zap.txt", находящегося в той же папке, что и программа, для работы
142     for(int i=0; i<=D.j; ++i)    // создание цикла, повторяющегося (D.j+1) раз
143     {
144         B[i]=B[i]/D.A[i];       // деление значений первой функций на значенийя второй для одного и того же значения переменной
145     }
146     for (int i=0; i<=D.j; ++i)      // создание цикла, рассчитанного на то же количество раз, что и предыдущий
147     {
148         out << B[i] << '\n';        // запись значений, полученных в предыдущем цикле, в файл
149     }
150     out.close();    // закрытие файла после записи в него значений
151     D.Viv();
152     std::cout << std::endl << "y ";
153     for (int i=0; i<=D.j; ++i)      // аналогичный предыдущему цикл, выводящий значения на экран
154     {
155         std::cout << B[i] << " ";
156     }
157 }
158 void Func::operator /(Func D)   // перегрузка оператора '/'
159 {
160     DelFunc(D);     // с помощью данного куска программы мы позволяем записать функцию в несколько ином виде: теперь запись f1/f2 будет работать аналогично записи f1.DelFunc(f2)
161 }
162 void Func::In (Func D)      // функция, интерполирующая первую функцию по второй
163 {
164     double l=c/D.c;     // создаем переменную, которой присваиваем значение, обозначающее, во сколько раз один шаг больше другого
165     c=D.c;      // приводим больший шаг к меньшему значению
166     z=D.j+1;    // ранее созданной переменной присваиваем значение, равное количеству элементов плюс один
167     int p=l;    // создаем целочисленную переменную, равную переменной l
168     B = new double [D.j+2];     // создание массива с количеством элементов D.j+2
169     D.Viv(); std::cout << std::endl << "y ";
170     B[0]=A[0]; std::cerr << B[0] << " ";    // присваиваем первому элементу нового массива значение первого элемента старого массива и выводим его на экран
171     int k=0;    // создаем вспомогательную целочисленную переменную
172     for (int i=0; i<=j; i+=p)   // создаем цикл, рассчитанный на j повторов через p
173     {
174         for (int m=1; m<p; ++m)     // создание цикла, выссчитывавшего промежуточное значение
175         {B[i+m]=((A[k]+A[k+1])/p)*(l-m); std::cerr << B[i+m] << " ";}   // присваиваем (i+m)-ому элементу значение, выссчитанного по формуле через заданные изначально значения и вывод егона экран
176         B[i+p]=A[k+1];      // присваивание значению (i+p)-ого элемента нового массива значения (k+1)-ого элемента старого массива
177         std::cerr << B[i+p] << " ";     // вывод высчитанного выше значения на экран
178         k=k+1; // увеличение k на единицу
179     }
180 }
181 void Func::App ()   // функция, аппроксимирующая полученную в результате сложения/вычитания/деления/умножения двух функций функцию
182 {
183     double d=0,e=0,f=0,g=0;     // создание переменных
184     double k=0,l=0;     // создание переменных
185     for (int i=0; i<z; ++i)     // цикл, который высчитывает сумму произведений зависимой и независимой переменных
186         {d=i*B[i]+d;}
187     for (int i=0; i<z; ++i)     // цикл, который высчитывает сумму всех значений функции
188         {e=B[i]+e;}
189     for (int i=0; i<z; ++i)     // цикл, высчитывающий сумму всех аргументов функции
190         {f=i+f;}
191     for (int i=0; i<z; ++i)     // цикл, высчитывающий сумму квадратов всех аргументов функции
192         {g=i*i+g;}
193     k=(z*d-f*e)/(z*g-f*f);      // расчет углового коэффициента прямой
194     l=(e-k*f)/z;        // расчет свободного коэффициента прямой
195     std::cout << "y=" << k << "x+" << l;    // вывод уравнения полученной прямой на экран
196     std::ofstream out("ap.txt");        // запись полученного уравнения в файл
197     {
198         out << "y=" << k << "x+" << l;
199     }
200     out.close();
201 }
202 
203 
204 
205 #include <iostream>
206 #include <fstream>
207 #include "Func.h"
208 
209 using namespace std;
210 double m,n,o, m1, n1, o1;
211 int a;
212 char b;
213 
214 int main()
215 {
216     cout << "Enter the beginning, the end and the step of a function." << endl; // ввод опорных значений первой функции: начало, конец, шаг;
217     cin >> m >> n >> o; // считывание значений
218     cout << "Enter the beginning, the end and the step of another function." << endl; // ввод опорных значений второй функции: начало, конец, шаг;
219     cin >> m1 >> n1 >> o1; // считывание значений
220     Func F(m,n,o); // создание объекта класса Func, определяющий первую функцию
221     cout << "The first function is" << endl; F.Viv(); cout << endl << "y ";
222     F.DefFunc(); // определение первой функции через создание массива с ее значениями
223     cout << endl;
224     Func F1(m1,n1,o1); // создание объекта класса Func, определяющий вторую функцию
225     cout << "The second function is" << endl; F1.Viv(); cout << endl << "y ";
226     F1.DefFunc(); // определение второй функции через создание массива с ее значениями
227     cout << endl;
228     cout << "As two functions have different steps, we made the interpolation of the first function." << endl;
229     F.In(F1); // линейная интерполяция первой функции по второй
230     cout << endl;
231     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;
232     cin >> a;
233     if (a==1)
234     {cout << "Function 1 + function 2 =" << '\n'; F+F1;}   // сложение двух функций с одинаковым шагом и интервалом
235     else if (a==2)
236     {cout << "Function 1 - function 2 =" << '\n'; F-F1;}   // вычитание двух функций с одинаковым шагом и интервалом
237     else if (a==3)
238     {cout << "Function 1 * function 2 =" << '\n'; F*F1;}   // умножение двух функций с одинаковым шагом и интервалом
239     else if (a==4)
240     {cout << "Function 1 / function 2 =" << '\n'; F/F1;}   // деление двух функций с одинаковым шагом и интервалом
241     cout << endl;
242     cout << "Enter 5 to do the approximation of the result function" << endl;   // пользователь сам выбирает, выполнять ли аппроксимацию;
243     cout << "Otherwise enter 6 to quit" << endl;
244     cin >> a;
245     if (a==5)
246     {cout << "Appromaximation:" << endl;
247     F.App();}   // аппроксимация
248     return 0;
249 }

Савельева Ольга

Краткое описание алгоритма : Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале. Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать методом наименьших квадратов. Данные берутся из файла. При считывании с файла сначала указывается отрезок, потом величина, а потом дискретные значения.

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 //Бибилотека необходимая для возможности включения русского языка в консоли
  4 #include <locale.h>
  5 
  6 class fun
  7 {
  8 	/*
  9 	fx - массив с дискретными значениями функции
 10 	a - начало отрезка определения функции
 11 	b - конец отрезка определения функции
 12 	dx - шаг
 13 	*/
 14 	double *fx, a, b, dx;
 15 	//Чтобы очусть ошибки округления в вещественных числах при сравнениях используется константа eps.
 16 	//К примеру два вещественных числа x и y сравниваются не так x>=y, а так x-y>=-eps.
 17 	const double eps = 1e-10; //1e-10 это тоже самое что 0.0000000001
 18 
 19 public:
 20 	//Коструктор по умолчанию
 21 	fun();
 22 	//Конструктор копирования
 23 	fun(fun &tmp);
 24 	//Деструктор
 25 	~fun();
 26 
 27 	//Перегруженные операторы. Ключевое слово const в конце означает, что объект от которого вызвается метод не изменяется
 28 	const fun operator+(const fun& right) const;
 29 	const fun operator-(const fun& right) const;
 30 	const fun operator*(const fun& right) const;
 31 	const fun operator/(const fun& right) const;
 32 	const fun& operator=(const fun& right);
 33 
 34 	//Метод считывания из файла
 35 	void readFile(const char *path);
 36 	//Метод вывода в файл
 37 	void writeFile(const char *path);
 38 
 39 	//Метод изменения шага
 40 	void changeDx(double newDx);
 41 	//Метод вычисления значения в заданной точке
 42 	double getX(double x1);
 43 };
 44 
 45 //В конструкторе по умолчанию все просто.
 46 fun::fun()
 47 {
 48 	a = b = dx = 0;
 49 	fx = NULL;
 50 }
 51 
 52 //Конструктор копирования
 53 fun::fun(fun &tmp)
 54 {
 55 	int i, n;
 56 	//Копирование свойств объекта tmp в текущий объект
 57 	a = tmp.a;
 58 	b = tmp.b;
 59 	dx = tmp.dx;
 60 	//Вычисление количества дискретных значений
 61 	n = (b - a) / dx + 1;
 62 	//Выделение необходимой памяти для хранения дискретных значений
 63 	fx = new double[n];
 64 	//Копирование дискретных значений объекта tmp в текущий объект
 65 	for (i = 0; i<n; ++i)
 66 		fx[i] = tmp.fx[i];
 67 }
 68 
 69 //Деструктор
 70 fun::~fun()
 71 {
 72 	//Освобождение памяти выделенной для массива дискретных значений
 73 	if (fx != NULL) delete[] fx;
 74 }
 75 //Оператор сложения.
 76 const fun fun::operator+(const fun& right) const
 77 {
 78 	//Создание результирующего объекта
 79 	fun result;
 80 	int i, n;
 81 	//Копирование свойств в результирующий объект
 82 	result.dx = dx;
 83 	result.a = a;
 84 	result.b = b;
 85 	//Вычисление количества дискретных значений
 86 	n = (b - a) / dx + 1;
 87 	//Выделение необходимой памяти для хранения дискретных значений
 88 	result.fx = new double[n];
 89 	//Вычисление дискретных значений результирующего объекта
 90 	for (i = 0; i<n; ++i)
 91 		result.fx[i] = fx[i] + right.fx[i];
 92 
 93 	//Возвращение результата
 94 	return result;
 95 }
 96 
 97 //Этот оператор аналогичен оператору сложение
 98 const fun fun::operator-(const fun& right) const
 99 {
100 	fun result;
101 	int i, n;
102 	result.dx = dx;
103 	result.a = a;
104 	result.b = b;
105 	n = (b - a) / dx + 1;
106 	result.fx = new double[n];
107 	for (i = 0; i<n; ++i)
108 		result.fx[i] = fx[i] - right.fx[i];
109 
110 	return result;
111 }
112 
113 //Этот оператор аналогичен оператору сложение
114 const fun fun::operator*(const fun& right) const
115 {
116 	fun result;
117 	int i, n;
118 	result.dx = dx;
119 	result.a = a;
120 	result.b = b;
121 	n = (b - a) / dx + 1;
122 	result.fx = new double[n];
123 	for (i = 0; i<n; ++i)
124 		result.fx[i] = fx[i] * right.fx[i];
125 
126 	return result;
127 }
128 
129 //Этот оператор аналогичен оператору сложение
130 const fun fun::operator/(const fun& right) const
131 {
132 	fun result;
133 	int i, n;
134 	result.dx = dx;
135 	result.a = a;
136 	result.b = b;
137 	n = (b - a) / dx + 1;
138 	result.fx = new double[n];
139 	for (i = 0; i<n; ++i)
140 		result.fx[i] = fx[i] / right.fx[i];
141 
142 	return result;
143 }
144 
145 //Оператор присваивания
146 const fun& fun::operator=(const fun& right)
147 {
148 	//Проверка на самоприсваивание
149 	if (this == &right)
150 		//Возвращение в качестве результата текущий объект
151 		return *this;
152 
153 
154 	int i, n;
155 	//Присваивание свойств объекта right текущему объекту
156 	a = right.a;
157 	b = right.b;
158 	dx = right.dx;
159 	//Вычисление количества дискретных значений
160 	n = (b - a) / dx + 1;
161 	//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
162 	if (fx != NULL) delete[] fx;
163 	//Выделение необходимой памяти для хранения дискретных значений
164 	fx = new double[n];
165 
166 	//Копирование дискретных значений объекта right в текущий объект
167 	for (i = 0; i<n; ++i)
168 		fx[i] = right.fx[i];
169 
170 	//Возвращение в качестве результата текущий объект
171 	return *this;
172 }
173 
174 /*
175 Метод считывания из файла
176 path - путь к файлу из которого считывать
177 */
178 
179 void fun::readFile(const char *path)
180 {
181 	//Открытие файла для считывания
182 	FILE *in = fopen(path, "r");
183 	int i, n;
184 	//Считывание границ отрезка и шага из файла
185 	fscanf(in, "%lf%lf%lf", &a, &b, &dx);
186 	//Вычисление количества дискретных значений
187 	n = (b - a) / dx + 1;
188 	//Если в текущем объекте есть какие-то дискретные значения, то их нужно удалить. То есть удалить память выделенную под них
189 	if (fx != NULL) delete[] fx;
190 	//Выделение необходимой памяти для хранения дискретных значений
191 	fx = new double[n];
192 	//Считывание дискретных значений из файла
193 	for (i = 0; i<n; ++i) fscanf(in, "%lf", &fx[i]);
194 	//Закрытие файла
195 	fclose(in);
196 }
197 
198 /*
199 Метод вывода в файл
200 path - путь к файлу в который нужно вывести
201 */
202 
203 void fun::writeFile(const char *path)
204 {
205 	//Открытие файла для вывода
206 	FILE *out = fopen(path, "w");
207 	int i, n;
208 	double x = a;
209 	//Вычисление количества дискретных значений
210 	n = (b - a) / dx + 1;
211 	//Вывод информации о отрезке и шаге в файл
212 	fprintf(out, "[%.5lf, %.5lf] dx=%.5lf\n", a, b, dx);
213 	//Последовательный вывод пары (точка, значение в точке) в файл
214 	for (i = 0; i<n; ++i, x += dx)
215 		fprintf(out, "x=%.5lf f(x)=%.5lf\n", x, fx[i]);
216 	//Закрытие файла
217 	fclose(out);
218 }
219 
220 /*
221 Метод изменения величины шага
222 */
223 void fun::changeDx(double newDx)
224 {
225 	int i, j, n, newN;
226 	double *newFx, x, newX, x1, y1, x2, y2, K, B;
227 	//Вычисление количества старых дискретных значений
228 	n = (b - a) / dx + 1;
229 	//Вычисление количества новых дискретных значений
230 	newN = (b - a) / newDx + 1;
231 	//Выделение памяти под новые дискретные значения
232 	newFx = new double[newN];
233 	//Определение первой точки в которой вычисляется новое дискретное значение
234 	newX = a;
235 	//Переменная которая бежит по старым дискретным значениям
236 	i = 0;
237 	//Определение первой точки в которой вычисляется старое дискретное значение
238 	x = a;
239 	//Цикл для формирования новых дискретных значений
240 	for (j = 0; j<newN; ++j, newX += newDx)
241 	{
242 		//В цикле находим отрезок где лежит точка в которой нужно вычислить новое дискретное значение
243 		for (; i<n - 1; ++i, x += dx)
244 			//Если без eps, то сравнения такие: x<=newX<=x+dx
245 			if ((newX - x>-eps) && ((x+dx) - newX>-eps))
246 			{
247 				//Линейная интерполяция
248 				x1 = x;
249 				x2 = x + dx;
250 				y1 = fx[i];
251 				y2 = fx[i + 1];
252 				K = (y2 - y1) / (x2 - x1);
253 				B = (y2*x1 - y1*x2) / (x1 - x2);
254 				//Вычисления значения в точке с помощью линейной интерполяции
255 				newFx[j] = newX*K + B;
256 				//Выход из цикла по i
257 				break;
258 			}
259 	}
260 	//Смена величины шага на новый
261 	dx = newDx;
262 	//Удаление старых дискретных значений
263 	delete[] fx;
264 	//Присвоение текущему объекту новых дискретных значений
265 	fx = newFx;
266 }
267 
268 /*
269 Метод вычисляет значение в точке xAns с помощью линейной интерполяции.
270 */
271 double fun::getX(double xAns)
272 {
273 	int i, n;
274 	double x, x1, y1, x2, y2, K, B;
275 	x = a;
276 	//Вычисление количества дискретных значений
277 	n = (b - a) / dx + 1;
278 	//Ищем отрезок в котором лежит точка xAns
279 	for (i = 0; i<n - 1; ++i, x += dx)
280 	{
281 		//Если без eps, то сравнения такие: x<=newX<=x+dx
282 		if (((x+dx) - xAns>-eps) && (xAns - x>-eps))
283 		{
284 			//Линейная интерполяция
285 			x1 = x;
286 			x2 = x + dx;
287 			y1 = fx[i];
288 			y2 = fx[i + 1];
289 			K = (y2 - y1) / (x2 - x1);
290 			B = (y2*x1 - y1*x2) / (x1 - x2);
291 			//Вычисления значения функции в заданной точке с помощью линейной интерполяции
292 			return K*xAns + B;
293 		}
294 	}
295 }
296 
297 int main()
298 {
299 	//Включение поддержки русского языка в консоли
300 	setlocale(LC_ALL, "Russian");
301 	//Объявление трех переменных типа fun
302 	fun a, b, c;
303 	//Считывания первых дискретных значений из файла inputA.txt
304 	a.readFile("inputA.txt");
305 	//Считывания вторых дискретных значений из файла inputB.txt
306 	b.readFile("inputB.txt");
307 
308 	//Первая функция
309 	a.writeFile("outputA.txt");
310 	//Вторая функция
311 	b.writeFile("outputB.txt");
312 
313 	c = a + b;
314 	//Результат сложения двух функций
315 	c.writeFile("outputAaddB.txt");
316 
317 
318 	c = a - b;
319 	//Результат вычитания второй функции из первой
320 	c.writeFile("outputAsubB.txt");
321 
322 	c = a*b;
323 	//Результат умножения двух функций
324 	c.writeFile("outputAmultiB.txt");
325 
326 	c = a / b;
327 	//Результат деления первой функции на вторую
328 	c.writeFile("outputAdivB.txt");
329 
330 	//У первой функции изменили шаг на 0.5
331 	a.changeDx(0.5);
332 	//Вывели её дискретные значения
333 	a.writeFile("outputChangeDx.txt");
334 
335 	//Функция, которая аппроксимирует её кусочно линейная.
336 	//Для примера нашли значение аппроксимируещей функции в точке не совпадающей с дискретными значениями.
337 	printf("Значение в точке 1.8 первой функции %.5lf\n", a.getX(1.8));
338 
339 	//Нужно чтобы окно консоли автоматически не закрылось 
340 	system("pause");
341 	return 0;
342 }


Скачать можно здесь


Сенников Иван

Суть программы: Программы позволяет задать 2 функции с любыми областями определения и любыми множествами значений, интерполировать их на любом шаге, аппроксимировать, а так же сложить 2 существующие функции. Программа написана в классе работы с функциями.

Идея: Класс работы с функциями содержит такие функции как функция введения данных функции - ее создание, перегрузки оператора сложения, линейных интерполяции и аппроксимации, выделения и освобождения памяти. Линейная интерполяция написана с помощью теории аналитической геометрии на плоскости, а линейная аппроксимация с помощью метода наименьших квадратов.

Инструкция: Программа выполнена в виде меню на английском языке: пользователю будет предоставлена возможность выйти из программы, создать обе функции, а также поработать с ними в индивидуальном порядке и сложить две уже существующие функции. Комментарии к программе написаны также на английском языке.

Ссылка для скачиваний: здесь.


Степанянц Степан

Краткое описание алгоритма : Программа создаёт и хранит значения двух функций с одинаковом шагом и заданных на одинаковом интервале.Методы позволяют сложить эти две функции,интерполировать одну из них по заданному шагу или апроксимировать,методом наименьших квадратов.Данныеберутся из файла.

  1 #include <iostream>
  2 #include <vector>
  3 #include <math.h>
  4 #include <fstream>
  5 #include <stdio.h>
  6 #include <string>
  7 #include <time.h>
  8  
  9 using namespace std;
 10  
 11 class func {
 12     vector <double> vals;
 13     double a, b, step, sz;
 14  
 15 public:
 16     func (string fil) { //конструктор для ввода функции из файла
 17         ifstream f(fil.c_str());
 18         double a, b, step, y;
 19         f >> a >> b >> step; //вводим основные значения из файла
 20         this->step = step;
 21         this->sz = (int)((b - a) / step + 1); //считаем размер
 22         this->a = a, this->b = b;
 23         for (int i = 0; i < this->sz; i++) {
 24             f >> y;
 25             this->vals.push_back(y); //считываем и записываем значения из файла
 26         }
 27         f.close();
 28     }
 29     func () {} //еще один конструктор
 30     func operator + (func a) { // эта и ближайшие четыре метода -- калькулятор функций
 31         func f = *new func(); //создаем новый экземпляр класса, ответ
 32         for (int i = 0; i < sz; i++) {
 33             f.vals.push_back(this->vals[i] + a.vals[i]); // складываем покоординатно
 34         }
 35         f.step = a.step; // копируем все значения в ответ (возможно, это можно сделать гораздо проще и не писать 4*4 строк но почему-то ничего умнее я не придумал)
 36         f.a = a.a;
 37         f.b = a.b;
 38         f.sz = a.sz;
 39         return f;
 40     }//Перегрузки операторов
 41     func operator - (func a) {
 42         func f = *new func();                   
 43         for (int i = 0; i < a.sz; i++) {
 44             f.vals.push_back(this->vals[i] - a.vals[i]);    //Вычитание
 45         }
 46         f.step = a.step;
 47         f.a = a.a;
 48         f.b = a.b;
 49         f.sz = a.sz;
 50         return f;
 51     }
 52     func operator * (func a) {
 53         func f = *new func();
 54         for (int i = 0; i < a.sz; i++) {
 55             f.vals.push_back(this->vals[i] * a.vals[i]);   //умножение
 56         }
 57         f.step = a.step;
 58         f.a = a.a;
 59         f.b = a.b;
 60         f.sz = a.sz;
 61         return f;
 62     }
 63     func operator / (func a) {
 64         func f = *new func();
 65         for (int i = 0; i < a.sz; i++) {
 66             f.vals.push_back(this->vals[i] / a.vals[i]);    // Деление
 67         }
 68         f.step = a.step;
 69         f.a = a.a;
 70         f.b = a.b;
 71         f.sz = a.sz;
 72         return f;
 73     }
 74  
 75     pair<double, double> approx() { //аппроксимация. 
 76         double mid = 0;
 77         for (int i = 0; i < this->sz; i++) {
 78             mid += this->a + i * this->step;
 79         }
 80         mid /= this->sz;
 81         double d = 0;
 82         for (int i = 0; i < this->sz; i++) {
 83             d += pow((this->a + i * this->step - mid), 2.);
 84         }
 85         double a = 0;
 86         for (int i = 0; i < this->sz; i++) {
 87             a += (this->a + i * this->step - mid) * this->vals[i];
 88         }
 89         a /= d;
 90         double midy = 0;
 91         for (int i = 0; i < this->sz; i++) {
 92             midy += this->vals[i];
 93         }
 94         midy /= this->sz;
 95         double c = midy - a * mid;
 96         return {a, c}; //{x,y} возвращает пару (на самом деле не пару а просто какой-нибудь объект) с первым значением x и вторым y
 97     }
 98  
 99     func inter(double step) {
100         func f = *new func(); //ответ
101         double curr2, curr1;
102         int j = 0;
103         f.a = this->a, f.b = this->b, f.step = step, f.sz = (int)((b - a) / step + 1);
104         for (int i = 0; i < f.sz; i++) {
105             curr2 = a + i * step;
106             curr1 = a + j * this->step;
107             while (curr1 + this->step <= curr2) {
108                 j++, curr1 += this->step;
109             }
110             if (curr1 == curr2) {
111                 f.vals.push_back(this->vals[j]);
112                 continue;
113             }
114             f.vals.push_back((this->vals[j + 1] - this->vals[j]) * (curr2 - curr1) / this->step + this->vals[j]);//я хз, тут видимо какая-то математика
115         }
116         return f;
117     }
118     void write(string fil) { //запись. чтобы записать не в файл, а в консоль вывести, надо передать "-1"
119         ofstream f(fil.c_str());
120         if (fil != "-1") {
121             f << this->a << ' ' << this->b << ' ' << this->step << '\n';
122         }
123         else
124             cout << this->a << ' ' << this->b << ' ' << this->step << '\n';
125         for (int i = 0; i < sz; i++) {
126             if (fil != "-1")
127                 f << this->vals[i] << '\n';
128             else
129                 cout << this->vals[i] << '\n';
130         }
131         f.close();
132  
133     }
134 };
135  
136 int main() {
137     string fil;
138     cout << "Input the file name with the function values\n";
139     cin >> fil;
140     func f = *new func(fil);
141     int a;
142     char ch;
143     double st;
144     while (true) {
145         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";
146         cin >> a;
147         if (a == 4) {
148             cout << "input file name to write to\n";
149             cin >> fil;
150             f.write(fil);
151         }
152         if (a == 3) {
153             auto t = f.approx();
154             cout << "Approximate line equation is y = " << t.first << " * x + " << t.second << '\n';
155         }
156         if (a == 2) {
157             cout << "input step to interpolate\n";
158             cin >> st;
159             f = f.inter(st);
160         }
161         if (a == 1) {
162             cout << "input arithmetic operator and file name with the second function values\n";
163             cin >> ch >> fil;
164             if (ch == '+') f = f + func(fil);
165             if (ch == '-') f = f - func(fil);
166             if (ch == '*') f = f * func(fil);
167             if (ch == '/') f = f / func(fil);
168         }
169         if (a == 5) {
170             cout << "Input the file name with the function values\n";
171             cin >> fil;
172             f = *new func(fil);
173         }
174         if (a == 6)
175             return 0;
176     }
177 }

Сюрис Александр Задаются две функции с разными шагами и начальными и конечными значениями. Аппроксимирует одну функцию по шагу другой и складывает/умножает/вычитает/делит их

Скачать можно тут.

  1 #include <iostream>
  2 #include <vector>
  3 #include<math.h>
  4 
  5 using namespace std;
  6 class f{
  7     private:
  8     double st, en, d; //начало, конец, дельта
  9     vector<double> v;//вектор, содержащий y
 10     public:
 11     f(double _st, double _en, double _d, vector<double> _v){
 12         st=_st;
 13         en=_en;
 14         d=_d;
 15         for(int i=0;i<_v.size();i++) //копируем массив, который вводим в консоль
 16             v.push_back(_v[i]);
 17         //return *this;
 18     }
 19     f(){};
 20     f aprox(double _st, double _en, double _d){ //метод интерполяции, поиск коэфф a и b для y=ax+b
 21         double sum_x=0, sum_y=0, sum_2x=0,sum_xy=0,a,b;
 22         for(int i=0; i<=(en-st)/d; i++)
 23             sum_x=sum_x+st+i*d;
 24         for(int i=0; i<=(en-st)/d; i++)
 25             sum_y=sum_y+v[i];
 26         for(int i=0; i<=(en-st)/d; i++)
 27             sum_2x=sum_2x+pow(st+i*d,2);
 28         for (int i=0; i<=(en-st)/d; i++)
 29             sum_xy=sum_xy+v[i]*(st+i*d);
 30         a=(((en-st)/d+1)*sum_xy-sum_x*sum_y)/(((en-st)/d+1)*sum_2x-sum_x*sum_x);
 31         b=(sum_y-a*sum_x)/(((en-st)/d+1));
 32 
 33         vector<double> v1;//вектор, содержащий проинтерполированную функцию
 34             for(int i=0; i<=(en-st)/d; i++)
 35                 v1.push_back(a*(st+i*d)+b);//добавление значений проинтерполированной ф-ции с шагом другой функции
 36         return f(_st,_en,_d,v1);
 37 
 38     }
 39 
 40      f operator +(f x){//оператор сложения
 41         double _en,_st,_d;
 42         _en=min(en,x.en); //поиск области пересечения
 43         _st=max(st,x.st);
 44         if (_en>_st){//проверяем, пересекаются ли функции
 45             vector<double> _v;
 46             f y;
 47             if(x.st<st){ //сравниваем начала двух отрезков, для того, чтобы выбрать, какую функцию апроксимировать
 48                 vector<double> _v;
 49                 y=x.aprox(_st, _en, d);
 50                 for (int i=0; i<=(_en-_st)/d; i++)
 51                     _v.push_back(y.v[i]+v[i]); //вектор с суммой функций
 52                 return f(_st,_en,d,_v);
 53             }
 54             else{
 55                 vector<double> _v;
 56                 y=this->aprox(_st, _en, x.d); //this-> функция, в которой мы работаем
 57                for (int i=0; i<=(_en-_st)/x.d; i++)
 58                     _v.push_back(y.v[i]+x.v[i]);
 59                 return f(_st,_en,x.d,_v);
 60             }
 61         }
 62     }
 63 
 64     f prot(){ //поиск противоположной функции
 65         for (int i=0; i<=(en-st)/d; i++)
 66             v[i]=(-1)*v[i];
 67         return *this;
 68     }
 69 
 70     f operator - (f x){ //разность функций
 71         return(*this + x.prot());
 72     }
 73 
 74 f operator *(f x){//оператор умножения
 75         double _en,_st,_d;
 76         _en=min(en,x.en); //поиск области пересечения
 77         _st=max(st,x.st);
 78         if (_en>_st){//проверяем, пересекаются ли функции
 79             vector<double> _v;
 80             f y;
 81             if(x.st<st){ //сравниваем начала двух отрезков, для того, чтобы выбрать, какую функцию апроксимировать
 82                 vector<double> _v;
 83                 y=x.aprox(_st, _en, d);
 84                 for (int i=0; i<=(_en-_st)/d; i++)
 85                     _v.push_back(y.v[i]*v[i]); //вектор с суммой функций
 86                 return f(_st,_en,d,_v);
 87             }
 88             else{
 89                 vector<double> _v;
 90                 y=this->aprox(_st, _en, x.d); //this-> функция, в которой мы работаем
 91                for (int i=0; i<=(_en-_st)/x.d; i++)
 92                     _v.push_back(y.v[i]*x.v[i]);
 93                 return f(_st,_en,x.d,_v);
 94             }
 95         }
 96     }
 97 
 98 f obr(){
 99    for (int i=0; i<=(en-st)/d; i++)
100             v[i]=1/v[i];
101         return *this;
102 }
103 
104 f operator /(f x){
105 return(*this*x.obr());
106 }
107 
108     void vivod(){ //вывод
109     for(int i=0; i<v.size(); i++)
110         cout<<v[i]<<" ";
111 
112     }
113 };
114 int main(){
115     setlocale(LC_ALL, "Russian");
116     double a,b,a1,b1,d,d1,t;
117     int o;
118     cout << "Введите начала и конец отрезка и дельту: ";
119     cin>>a>>b>>d;
120     int amount=(b-a)/d+1,amount2;
121     vector<double>x;
122     cout << "Введите " << amount << " значений функции на данном интервале:";
123     for (int i=0; i<amount; i++)
124     {
125         cin>>t;
126         x.push_back(t);
127     }
128 
129     cout << "Проделаем ровно то же самое для 2 функции ";
130     cout << "Введите начала и конец отрезка и дельту: ";
131     cin >> a1 >> b1 >> d1;
132 
133     amount2=(b1-a1)/d1+1;
134     vector<double>y;
135     cout << "Введите " << amount2 << " значений функции на данном интервале:";
136     for (int i=0; i<amount2; i++)
137     {
138         cin>>t;
139         y.push_back(t);
140     }
141     f g(a,b,d,x);
142     f h(a1,b1,d1,y);
143 
144     cout<<"Выберете дейстивя с функциями: +, -, *, \ " << endl;
145     cout<<"Введите число, соответсвующее порядковому номеру операции(1-4) - ";
146     cin>>o;
147     if(o==1){               //по невыясненным причинам одновременно написанные слева идущие if -ы не работают,
148         cout<<"Сумма:";     //но если заккоментить их и менять знак + в скобке на другие, то все работает
149         (g+h).vivod();
150 
151     }
152 
153     if(o==2){
154         cout<<"Разность:"
155         (g-h).vivod();
156 
157     }
158 
159     if(o==3){
160         cout<<"Произведение:"
161         (g*h).vivod();
162 
163 
164     }
165 
166      if(o==3){
167         cout<<"Отношение:"
168         (g/h).vivod();
169     }
170 
171 
172 }

Тимошенко Валентина

Краткое описание алгоритма: в классе создаются две различные функции, а также функции для осуществления арифметических операций - сложения, вычитания, умножения и деления. Кроме того, созданы функции интерполяции и аппроксимации результата. Все результаты записываются в файлы, названия которых выводятся на экран в процессе работы программы.

Инструкция к программе: при запуске программа предлагает ввести начало интервала, его конец и шаг для обеих функций. Далее пользователь выбирает одну из предложенных арифметических операций - сложение, вычитание, умножение или деление. После проведения вычислений программа предлагает пользователю интерполировать и аппроксимировать результат выбранной арифметической операции. Пользователь может давать команды на выполнение арифметических операций неограниченное число раз, программа завершает работу по команде пользователя.


Скачать программу можно здесь: [4].

  1 #include <iostream> ///программа, перегружающая операторы для работы с двумя функциями,
  2 #include <fstream>  ///интерполирующая и аппроксимирующая результат арифметических операций над этими функциями
  3 #include <math.h>
  4 
  5 using namespace std;
  6 
  7 class functions ///класс, хранящий значения введенных пользователем значений начала и конца исследуемого интервала, а также шага функции
  8 {
  9 private:
 10     double *massiv1, *massiv2, *massiv3; ///указатели на массивы, которые будут использованы в программе
 11     ///massiv1 - массив, хранящий изначальные значения функций, massiv2 - массив, хранящий значения одной из функций после интерполяции
 12     ///massiv3 - массив, хранящий значения суммы/разности/умножения/деления функций
 13     double quantity_before_interpolation, Begin, End, Step;
 14     ///quantity - количество элементов в массиве(переменная типа double), Begin и End - начало и конец рассматриваемого отрезка, Step - шаг функции
 15 
 16 public:
 17 
 18     int amount_before_interpolation; ///amount - количество элементов в массиве (переменная типа int)
 19     functions (double Begin1, double End1, double Step1 ):Begin(Begin1), End(End1), Step(Step1) ///переменные, в которые закладываются значения, введенные пользоватедем
 20     {
 21         quantity_before_interpolation =((End-Begin)/Step) + 1; ///расчёт количества элементов в массиве
 22         amount_before_interpolation = static_cast < int >(quantity_before_interpolation); ///перевод значения количества элементов из типа double в тип int
 23     }
 24 
 25     void function1(double Begin, double End, double Step) ///задание первой функции
 26     {
 27         massiv1 = new double [amount_before_interpolation]; ///создание массива для хранения значений функций
 28         ofstream out ("Function1.txt"); ///запись в файл значений первой функции
 29         out << "The size of the range = " << amount_before_interpolation << '\n' << endl;; ///вывод на экран количества элементов данного массива
 30         for (int i = 0; i < amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 31         {
 32             massiv1[i] = 2*i*Step+Begin; ///формула вычисления
 33             out << "y(x=" << i << ")= " << massiv1[i] << endl; ///вывод на экран полученных значений
 34         }
 35         out.close(); ///завершение записи в файл
 36     }
 37 
 38     void function2(double Begin,double End,double Step) ///задание второй функции
 39     {
 40         massiv1 = new double [amount_before_interpolation]; ///создание массива для хранения значений функции
 41         ofstream out ("Function2.txt"); ///запись в файл значений второй функции
 42         out << "The size of the range = " << amount_before_interpolation << '\n' << endl;; ///вывод на экран количества элементов данного массива
 43         for (int i = 0; i < amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
 44         {
 45             massiv1[i] = i*Step; ///формула вычисления
 46             out << "y(x=" << i << ")= " << massiv1[i] << endl; ///вывод на экран полученных значений
 47         }
 48         out.close(); ///завершение записи в файл
 49     }
 50 
 51     void interpolation (double Begin1, double End1, double Step2) ///интерполяция результата по новому шагу
 52     {
 53         ofstream out ("Interpolation.txt"); ///запись в файл интерполированных значений функции
 54         double quantity_after_interpolation =((End1-Begin1)/Step2) + 1; ///расчёт количества элементов в массиве
 55         int amount_after_interpolation = static_cast < int > (quantity_after_interpolation); ///перевод значения количества элементов из типа double в тип int
 56         out << "After interpolation the size of range = " << amount_after_interpolation << '\n' << endl;
 57 
 58         massiv3 = new double [amount_after_interpolation]; ///создание массива для хранения значений функции
 59         for (int i = 0; i < amount_after_interpolation; ++i) ///цикл, вычисляющий значения функции
 60         {
 61             double x = i*Step2 + Begin1; ///расчёт х-вой координаты
 62             double x0 = static_cast < int >((x - Begin1)/Step + Begin1); ///расчёт нулевой х-вой координаты
 63             ///перевод значения х0 из типа double в тип int
 64             ///расчёт х-вой координаты, считая от введенного значения начала интервала
 65             double x1 = x0 + Step; ///расчёт следующего значения х-вой координаты
 66             int i_0 = (x - Begin1)/Step; ///расчёт нулевого индекса
 67             int i0 = static_cast < int > (i_0); ///перевод нулевого индекса из типа double в тип int
 68             int i1 = i0 + 1; ///расчёт следующего индекса
 69             massiv3[i]=(((x - x0)*(massiv2[i1] - massiv2[i0]))/(x1-x0)) + massiv2[i0]; ///формула вычисления
 70             out <<  "y(x=" << i << ")= " << massiv2[i] << endl; ///вывод на экран полученных значений
 71         }
 72         out.close(); ///завершение записи в файл
 73     }
 74 
 75     void approximation(double Begin1, double End1, double Step2) ///функция, аппроксимирующая результат сложения/вычитания/умножения/деления функций
 76     {
 77         amount_before_interpolation=(End1-Begin1)/Step2+1;
 78         int SIZE = static_cast <int> (amount_before_interpolation); /// для удобства вводим переменную SIZE и закладываем в нее значение размера массива
 79 
 80         ///обнуление переменных
 81         double sumX = 0; ///переменная, хранящая значение суммы х-вых координат
 82         double sumY = 0; ///переменная, хранящая значение суммы у-вых координат
 83         double sumXY = 0; ///переменная, хранящая значение суммы произведений х-вой и у-вой координат
 84         double sumX2 = 0; ///переменная, хранящая значение суммы х-вых координат, взятых в квадрате
 85         double k=0; ///переменная, хранящая значения углового коэффициента касательной к графику данной функции
 86         double b=0; ///переменная, хранящая значение свободного коэффициента
 87         double d;
 88 
 89         ofstream out ("Approximation.txt"); ///запись в файл аппроксимированных значений
 90         for (int i = 0; i < SIZE; ++i) ///цикл для расчёта сумм, указанных выше
 91         {
 92             d=i*Step2+Begin1; ///расчёт х-вой координаты
 93 
 94             sumX = d + sumX; ///расчёт суммы х-вых координат
 95 
 96             sumY = massiv3[i] + sumY; ///расчёт суммы у-вых координат
 97 
 98             sumXY = d*massiv3[i] + sumXY; ///расчёт суммы произведений х-вой и у-вой координат
 99 
100             sumX2 = d*d + sumX2; ///расчёт суммы х-вых координат, взятых в квадрате
101         }
102 
103         k =(SIZE*sumXY - sumX*sumY)/(SIZE*sumX2- sumX*sumX); ///расчёт углового коэффициента
104 
105         b =(sumY - k*sumX)/SIZE; ///расчёт свободного коэффициента
106 
107         out << "The equation, which is got as a result of approximation" << endl; ///вывод уравнения на экран
108 
109         if (b > 0) ///вывод уравнения при положительном свободном коэффициенте
110         {
111             out << "y = " << k << "*x+" << b << endl;
112         }
113 
114         else if (b < 0) ///вывод уравнения при отрицательном свободном коэффициенте
115         {
116             out << "y = " << k <<"*x" << b << endl;
117         }
118         out.close(); ///завершение записи в файл
119     }
120 
121     ///перегрузка операторов
122 
123     functions operator+ (functions func3) ///сумма двух функций
124     {
125         massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
126 
127         ofstream out ("Results_of_sum.txt"); ///запись в файл значений после суммирования значений функций
128         out << "sum of the functions" << '\n' << endl;
129 
130         for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
131         {
132             massiv2[i] = massiv1[i] + func3.massiv1[i]; ///формула вычисления
133             out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
134         }
135         out.close(); ///завершение записи в файл
136 
137         char d; ///переменная для команды интерполировать результат
138         cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
139         cin >> d;
140 
141         if (d=='+') ///если команда для интерполяции дана
142         {
143             double Step2; ///переменная, хранящая значение нового шага
144             cout << '\n' << "Input the step for interpolation" << endl;
145             cin >> Step2;
146             interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
147 
148             char w; /// переменная для команды аппроксимировать результат
149             cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
150             cin >> w;
151 
152             if (w=='+') ///если команда на аппроксимацию дана
153             {
154                 approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
155             }
156         }
157     }
158 
159     functions operator- (functions func3) ///разность двух функций
160     {
161         massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
162 
163         ofstream out ("Results_of_difference.txt"); ///запись в файл значений второй функции
164         out << "difference of the functions" << '\n' << endl;
165 
166         for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
167         {
168             massiv2[i] = massiv1[i] - func3.massiv1[i]; ///формула вычисления
169             out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
170         }
171         out.close(); ///завершение записи в файл
172 
173         char d; ///переменная для команды интерполировать результат
174         cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
175         cin >> d;
176 
177         if (d=='+') ///если команда для интерполяции дана
178         {
179             double Step2; ///переменная, хранящая значение нового шага
180             cout << '\n' << "Input the step for interpolation" << endl;
181             cin >> Step2;
182             interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
183 
184             char w; /// переменная для команды аппроксимировать результат
185             cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
186             cin >> w;
187 
188             if (w=='+') ///если команда на аппроксимацию дана
189             {
190                 approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
191             }
192         }
193     }
194 
195     functions operator* (functions func3) ///произведение двух функций
196     {
197         massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
198 
199         ofstream out ("Results_of_multiplying.txt"); ///запись в файл значений второй функции
200         out << "multiplying of the functions" << '\n' << endl;
201 
202         for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
203         {
204             massiv2[i] = massiv1[i] * func3.massiv1[i]; ///формула вычисления
205             out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
206         }
207         out.close(); ///завершение записи в файл
208 
209         char d; ///переменная для команды интерполировать результат
210         cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
211         cin >> d;
212 
213         if (d=='+') ///если команда для интерполяции дана
214         {
215             double Step2; ///переменная, хранящая значение нового шага
216             cout << '\n' << "Input the step for interpolation" << endl;
217             cin >> Step2;
218             interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
219 
220             char w; /// переменная для команды аппроксимировать результат
221             cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
222             cin >> w;
223 
224             if (w=='+') ///если команда на аппроксимацию дана
225             {
226                 approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
227             }
228         }
229     }
230 
231     functions operator/ (functions func3) ///деление двух функций
232     {
233         massiv2=new double[amount_before_interpolation]; ///создание массива для хранения значений функций
234 
235         ofstream out ("Results_of_dividing.txt"); ///запись в файл значений после деления значения первой функции на значения второй функции
236         out << "dividing of the functions" << '\n' << endl;
237 
238        for (int i=0; i<amount_before_interpolation; ++i) ///цикл, вычисляющий значения функции
239         {
240             massiv2[i] = massiv1[i] / func3.massiv1[i]; ///формула вычисления
241             out << "y (x=" << i << ") = " << massiv2[i] << "\n"; ///вывод на экран полученных значений
242         }
243         out.close(); ///завершение записи в файл
244 
245         char d; ///переменная для команды интерполировать результат
246         cout << '\n' << "If you want to interpolate the results, input +, in not, input -" << endl;
247         cin >> d;
248 
249         if (d=='+') ///если команда для интерполяции дана
250         {
251             double Step2; ///переменная, хранящая значение нового шага
252             cout << '\n' << "Input the step for interpolation" << endl;
253             cin >> Step2;
254             interpolation(Begin, End, Step2); ///вызов функции и интерполяция результата
255 
256             char w; /// переменная для команды аппроксимировать результат
257             cout << '\n' << "If you want to approximate the results, input +, in not, input -" << endl;
258             cin >> w;
259 
260             if (w=='+') ///если команда на аппроксимацию дана
261             {
262                 approximation(Begin, End, Step2); ///вызов функции и аппроксимация результата
263             }
264         }
265     }
266 };
267 
268 int main()
269 {
270     double Begin1, End1, Step1; ///переменные, вводимые пользователем
271     cout << "Input the beginning of the interval" << endl; ///ввод начала отрезка
272     cin >> Begin1;
273     cout << '\n' << "Input the end of the interval" << endl; ///ввод конца отрезка
274     cin >> End1;
275     cout << '\n' << "Input the step of functions" << endl; ///ввод начального шага функций
276     cin >> Step1;
277 
278     functions func1(Begin1, End1, Step1); ///вызов первой функции
279     func1.function1(Begin1, End1, Step1);
280     cout <<'\n' << "Meanings of the first function are saved in file called 'Function1.txt'" << endl;
281 
282     functions func2(Begin1, End1, Step1); ///вызов второй функции
283     func2.function2(Begin1, End1, Step1);
284     cout <<'\n' << "Meanings of the second function are saved in file called 'Function2.txt'" << endl;
285 
286     functions func3(Begin1,End1,Step1); ///вызов третьей функции
287 
288     char s; ///переменная, используется в цикле
289     do
290     {
291         char c; ///переменная, хранящая выбор арифметической операции пользователем
292         cout << '\n' << "Input your choice: + for sum,- for difference,* for multiplying,/ for dividing" << endl;
293         cin >> c;
294 
295         if (c=='+') ///цикл, запускающий функцию расчёта суммы двух функций, их интерполяцию и аппроксимацию
296         {
297             func3=func1+func2; ///формула расчёта суммы
298             cout << '\n' << "Results of sum are saved in file called 'Results_of_sum.txt'" << endl;
299             cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
300             cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
301         }
302         if (c=='-') ///цикл, запускающий функцию расчёта разности двух функций, их интерполяцию и аппроксимацию
303         {
304             func3=func1-func2; ///формула расчёта разности
305             cout << '\n' << "Results of difference are saved in file called 'Results_of_difference.txt'" << endl;
306             cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
307             cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
308         }
309         if (c=='*') ///цикл, запускающий функцию расчёта произведения двух функций, их интерполяцию и аппроксимацию
310         {
311             func3=func1*func2; ///формула расчёта произведения
312             cout << '\n' << "Results of multiplying are saved in file called 'Results_of_multiplying.txt'" << endl;
313             cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
314             cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
315         }
316         if (c=='/') ///цикл, запускающий функцию расчёта частного двух функций, их интерполяцию и аппроксимацию
317         {
318             func3=func1/func2; ///формула расчёта частного
319             cout << '\n' << "Results of dividing are saved in file called 'Results_of_dividing.txt'" << endl;
320             cout << '\n' << "Result of interpolation is saved in file called 'Interpolation.txt'" << endl;
321             cout << '\n' << "Result of approximation is saved in file called 'Interpolation.txt'" << endl;
322         }
323 
324         cout << '\n' << "If you want program continue counting, input +, if not, input -" << endl;
325         ///команда пользователя на продолжение работы цикла или же на его завершение
326         cin >> s;
327 
328         if (s=='-') ///если дана команда на завершение работы цикла
329         {
330             cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
331             cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
332             return 0;
333         }
334     }
335     while (s != '-'); ///работа цикла не завершается до тех пор, пока пользователь не даст соответствующую команду
336 
337 }

Уманский Александр

Инструкция к программе: пользователь вводит начало и конец отрезка и шаг для функций, после чего создается две функции. Затем функции суммируются, после чего пользователь вводит значение нового шага, суммированная функция интерполируется по новому шагу, после этого по МНК(методу наименьших квадратов) функция апроксимируется.


Скачать программу можно по ссылке

Метод наименьших квадратов задача состоит в том, чтобы минимизировать выражение: 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.


  1 #include <iostream>
  2 #include <math.h>
  3 #include <iomanip>
  4 #include<stdlib.h>
  5 using namespace std;
  6 
  7 class func
  8 {
  9 private:
 10     double a/*начало*/,b/*конец*/,c/*шаг*/,k/**/,m/**/,rr/**/;
 11     int d/*переменная для изменения типа, кол-во элементов для начальных элементов*/,tt/*переменная для изиенения типа, кол-ва элементов для счёта суммы*/;
 12     double *F/*массив для значений У*/, *X/*Массив для значений Х*/, *R/*массив для значений У после интерполяции*/, *Q;
 13 public:
 14 
 15     func (double a1, double b1, double c1):a(a1),b(b1),c(c1)//создаём конструктор для функции
 16     {
 17         double p = (b-a)/c;
 18         d = (int)p;
 19         if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
 20         else d += 1;
 21 
 22         F = new double [d];//создание динамического массива для У
 23         X = new double [d];// создание динамического массива для Х
 24         X[0]=a;//первый элемент
 25         X[d-1]=b;//последний элемент, для того чтобы последний элемент был в конце промежутка, чтобы его не потерять
 26         for(int i = 1; i < d-1; i++) X[i]=a+c*i; //присваивание значений всех Х
 27 
 28     }
 29      void first ()//функция для первой функции
 30     {
 31         double y;//в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
 32         F[0]=pow(2,a);//объявление значения У для начала промежутка
 33         F[d-1]=pow(2,b);//объявление значения У для конца промежутка
 34         for(int i = 1; i < d-1; ++i)
 35         {
 36             y = pow(2,((c*i)+a));//высчитываем значения У внутри промежутка
 37             F[i] = y;//присваиваем массиву значения по У
 38         }
 39 
 40         cout << " " << endl;//пробел и конец строки
 41     }
 42 
 43     void second ()//функция для второй функции
 44     {
 45         if(a==0 || b==0) return;
 46         F[0]=1*a*a; //присваивание значения функции в начале промежутка
 47         F[d-1]=1*b*b;//присваивание значения функции в конце промежутка
 48 
 49         for(int k = 1; k <d-1; ++k)
 50         {
 51             double n = c*k+a;
 52             if (n != 0)//условие неделимости на ноль
 53             {
 54                 F[k] = 1*n*n;
 55             }
 56         }
 57 
 58     }
 59 
 60     void operator +(func Q)//перегрузка оператора +
 61     {
 62         sum(Q);
 63     }
 64 
 65     void sum (func Q)//функция суммирования функций на интерполированном шаге
 66     {  double m, p = (b-a)/c;
 67     int i;
 68         R=new double[d+2];
 69           if (b > (d*c+a)) d += 2; //в зависимости от случая прибавляем либо 2 либо 1, чтобы не произошло переполнения массива
 70         else d += 1;
 71      m=a;
 72  cerr<<"\n";
 73 
 74         for(i = 0; i <d-1; ++i)//цикл суммирования функций и вывода значений суммы, функций и иксов
 75         {
 76 
 77             cerr <<"YFirst: "<< F[i] << "   ";
 78             cerr << "YSecond: "<< Q.F[i] << "   ";
 79             R[i] = F[i] + Q.F[i];
 80             cerr << "Ysum: "<< R[i] << "   ";
 81             cerr << "X:" << m << '\n';
 82 
 83             m=m+c;
 84         }
 85    for(i = 0; i <d-1; ++i)
 86         {Q.F[i]=R[i];
 87 }
 88         cerr << " " << endl;
 89     }
 90 
 91  double interp( double pnt/*новый шаг*/, func Q)//функция для интерполяции функции
 92     {double p,h,i,w,*X,aApr,bApr,X2sm,XYsm,Xsm/*хранит сумму интерполированных иксов*/,Ysm/*хранит сумму интерполированных игреков*/;
 93     int q,k,l,o;
 94     p=(b-a)/pnt+1;
 95     q=int(p);
 96     R=new double [q];
 97     X=new double [q];
 98 
 99     l=0;
100     k=0;
101 
102     for(h=a/*начало функции*/; h<=b/*конец функции*/; h=h+c/*старый шаг*/) //шагает по нормальному шагу
103     {
104         for(i=a-1; i<=b; i=i+pnt/*новый шаг*/)
105            if((i>h)&&(i<=(h+c)))//проверяет лежит ли новый шаг между точками старого
106             {   R[k]=(Q.F[l]-Q.F[l-1])*(i-h)/c+Q.F[l-1];//формула интерполяции
107                 cout<<"\n"<<"Yinter: "<<R[k]<<"  "<<"X: "<<i-1;//вывод интерполированных значений и иксов
108                 X[k]=i-1;
109                 k++;
110             }
111         l++;
112     }
113     cout<<"\n";
114     cout<<"\n";
115     cout<<"\n";
116     //обнуление значений сумм для МНК
117     Xsm=0;
118     Ysm=0;
119     XYsm=0;
120     X2sm=0;
121 
122     for(o=0;o<=k;o++)//цикл подготавливает суммы для МНК
123         {Xsm+=X[o];
124          Ysm+=R[o];
125          XYsm+=X[o]*R[o];
126          X2sm+=X[o]*X[o];
127          }
128 
129 aApr=(k*XYsm-Xsm*Ysm)/(k*X2sm-Xsm*Xsm);//находим коэфициенты по МНК
130 bApr=(Ysm-a*Xsm)/k;
131 cout<<"\n"<<"aAprox"<<a<<"  "<<"bAprox"<<b<<"\n";//выводим их
132  for(o=0;o<k;o++)
133         {c=aApr*X[o]+bApr;//считаем значение Y при данных коэфициентах
134         cout<<"YAprox: "<<c<<" "<<"X:"<<X[o]<<"\n" ;
135         }
136 
137 
138     return 0;}
139 };
140 
141 int main(){
142      double x, xn, s1,pnt;
143     cout << "Input the beginning of the function: " << endl;
144     cin >> x;
145     cout << "Input the ending of the function: " << endl;
146     cin >> xn;
147     cout << "Input step for the function: " << endl;
148     cin >> s1;
149     func H(x,xn,s1);
150     H.first();
151     func G(x,xn,s1);
152     G.second();
153     H+G;
154     cout<<"\n" << "Input new step for the function: " << endl;
155     cin >> pnt;
156     H.interp(pnt,G);
157 
158 return 0;}