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

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

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

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

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

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

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