/*
* main.cpp
*
* Created on: 20.03.2009
* Author: kostyan
*/
#include <iostream>
#include <fstream>
#include "GL/glu.h"
#include "GL/glut.h"
using namespace std;
double *x_array, *y_array;//здесь будут хранится измеренные значения
int n;//длина массивов
long double a1, a2, a3;//коэффициенты ф-ии
/*float scale_x=1.0, scale_y=1.0, scale_z=1.0;
void ChangeSize(GLsizei w, GLsizei h)//меняет наблюдаемый объём и поле просмотра
{
GLfloat range=200.0f;
if (h==0) h=1;//на случай деления на ноль
if (w==0) w=1;
glViewport(0, 0, w, h);//обновление системы координат
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w<=h) glOrtho(-range, range, -range*h/w, range*h/w, -range, range);//устанавливается объём отсечения с помощью отсекающих плоскостей
else glOrtho(-range*w/h, range*w/h, -range, range, -range, range);//левая, правая, нижняя, верхняя, ближняя, дальняя
glMatrixMode(GL_MODELVIEW);//обновление стека матрицы проекции модели
glLoadIdentity();
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);//очистка буферов цвета
//построение графика измерений
glPushMatrix();
glScalef(scale_x, scale_y,0.0);
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE);
glVertex2f(-200.0, 0.0);
glVertex2f(200.0, 0.0);
//glVertex2f(0.0, 200.0);
//glVertex2f(0.0, -200.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINE_STRIP);
for (int i=0; i<n; i++)
{
glVertex2d(x_array[i], y_array[i]);
}
glEnd();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINE_STRIP);
for (int i=0; i<200; i++)
glVertex2f((float) i, a1+a2*i+a3*i*i);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void SetupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//цвет для очистки окна
}
void Keyboard(unsigned char key, int x, int y)
{
if (key=='-')
{
scale_x-=1.0;
scale_y-=1.0;
scale_z-=1.0;
RenderScene();
}
if (key=='+')
{
scale_x+=1.0;
scale_y+=1.0;
scale_z+=1.0;
RenderScene();
}
}
void create_graphic(int argcp, char **argv)
{
glutInit(&argcp, argv);//инициализация GLUT
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);//тип режима отображения двойная буферизация и режим цвета РГБ
glutCreateWindow("Graphics");//создаём окно с заголовком
SetupRC();//в этой функции все начальные настройки
glutKeyboardFunc(Keyboard);//обработка клавиатуры
glutDisplayFunc(RenderScene);//RenderScene - ф-ия обратного вызова дисплея
glutReshapeFunc(ChangeSize);//вызываем ChangeSize при любом изменении размера окна
glutMainLoop();//запуск оболочки glut
}
*/
void print_matrix(long double **m)//вывод матрицы
{
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++) cout<<m[i][j]<<" ";
cout<<endl;
}
}
long double det(long double **m)//вычисление определителя методом треугольников
{
return m[0][0]*m[1][1]*m[2][2]+m[0][1]*m[1][2]*m[2][0]+m[1][0]*m[0][2]*m[2][1]-m[0][2]*m[1][1]*m[2][0]-m[0][1]*m[1][0]*m[2][2]-m[0][0]*m[1][2]*m[2][1];
}
int main(int argcp, char **argv)
{
cout<<"RAILWAY 1.0"<<endl;//приветствие
ifstream file;
char *filename=new char[256];
do//открываем файл с данными
{
cout<<"Please, enter correct filename of input file: ";
cin>>filename;
file.open(filename);
}
while (!file.is_open());
int num=0;
long double temp;
while (file>>temp) num++;//считаем кол-во измерений
file.close();
ifstream file2;
file2.open(filename);//переходим к началу файла
delete[] filename;//осовбождаем память
if (num%2!=0)//количественная проверка входных данных
{
cout<<"ERROR! Wrong data!"<<endl;
return -1;
}
n=num/2;
x_array=new double[n];//массивы значений
y_array=new double[n];
for (int i=0; !file2.eof(); i++)//считывание значений
{
file2>>x_array[i];
file2>>y_array[i];
}
file2.close();
long double **main_matrix=new long double*[3];//главная матрица построенная их коэффициентов системы
for (int i=0; i<3; i++) main_matrix[i]=new long double[3];
long double free_members[3];//вектор свободных членов
for (int i=0; i<3; i++)//обнуление всех элементов
{
free_members[i]=0.0;
for (int j=0; j<3; j++) main_matrix[i][j]=0.0;
}
main_matrix[0][0]=(long double) n;//самый первый элемент - кол-во опытов
long double pow=0.0;//для уменьшения количества операуий умножения
for (int i=0; i<n; i++)//заполнение матриц, подсчёт сумм
{
pow=x_array[i];//первая степень
main_matrix[0][1]+=pow;//сумма всех х
free_members[0]+=y_array[i];//сумма у
free_members[1]+=y_array[i]*pow;//сумма произведения соответствующих у*х
pow=pow*pow;//вторая степень
main_matrix[0][2]+=pow;//сумма квадратов всех х
free_members[2]+=y_array[i]*pow;//сумма произведений соответсвующих у*х^2
pow=pow*x_array[i];//третья степень
main_matrix[1][2]+=pow;//сумма кубов всех х
pow=pow*x_array[i];//четвёртая степень
main_matrix[2][2]+=pow;//сумма четвёртых степеней всех х
}
//заполнение повторных коэффициентов
main_matrix[1][0]=main_matrix[0][1];
main_matrix[1][1]=main_matrix[0][2];
main_matrix[2][0]=main_matrix[0][2];
main_matrix[2][1]=main_matrix[1][2];
print_matrix(main_matrix);
long double main_det=det(main_matrix);//вычисляем главный определитель
//создание матриц для коэффициентов a1, a2, a3
long double **a1_matrix=new long double*[3];
long double **a2_matrix=new long double*[3];
long double **a3_matrix=new long double*[3];
for (int i=0; i<3; i++)
{
a1_matrix[i]=new long double[3];
a2_matrix[i]=new long double[3];
a3_matrix[i]=new long double[3];
}
for (int i=0; i<3; i++)//заполнение матриц (вместо соответствующих коэффициентов ставятся свободные члены)
{
a1_matrix[i][0]=free_members[i];
a1_matrix[i][1]=main_matrix[1][i];
a1_matrix[i][2]=main_matrix[2][i];
a2_matrix[i][0]=main_matrix[0][i];
a2_matrix[i][1]=free_members[i];
a2_matrix[i][2]=main_matrix[2][i];
a3_matrix[i][0]=main_matrix[0][i];
a3_matrix[i][1]=main_matrix[1][i];
a3_matrix[i][2]=free_members[i];
}
//вывод матриц
cout<<"A1 matrix: "<<endl;
print_matrix(a1_matrix);
cout<<"A2 matrix: "<<endl;
print_matrix(a2_matrix);
cout<<"A3 matrix: "<<endl;
print_matrix(a3_matrix);
//вычисление определителей мариц коэффициентов
long double a1_det=det(a1_matrix);
long double a2_det=det(a2_matrix);
long double a3_det=det(a3_matrix);
//возможные случаи
if (main_det==0 && a1_det!=0 && a2_det!=0 && a3_det!=0) cout<<"No solution!"<<endl;
else if (main_det==0 && a1_det==0 && a2_det==0 && a3_det==0) cout<<"Infinity of soltions!"<<endl;
else
{
a1=a1_det/main_det;
a2=a2_det/main_det;
a3=a3_det/main_det;
cout<<"p(x)="<<a1<<"+"<<a2<<"x+"<<a3<<"x^2"<<endl;
}
//освобождение памяти
delete[] main_matrix;
delete[] a1_matrix;
delete[] a2_matrix;
delete[] a3_matrix;
/*cout<<"Do you want to see graphics of function? (y/n): ";
char voice;
cin>>voice;
if (voice=='y') create_graphic(argcp, argv);*/
delete[] x_array;//освобождаем память
delete[] y_array;
return 0;
}