Cod sursa(job #2419326)

Utilizator ArkinyStoica Alex Arkiny Data 8 mai 2019 01:54:13
Problema Algoritmul lui Gauss Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.37 kb
#include<iostream>
#include<fstream>
#include<string>
#include<string.h>
#include<math.h>
using namespace std;

class MatrixError
{
	string err;
public:
	MatrixError(const string &err)
	{
		this->err = err;
	}
};

template<class T>
class Matrix
{
	friend class LinearRegression;

	T **values;

	int N, M;

public:

	Matrix()
	{
		N = M = 0;

        values = NULL;
	}

	Matrix operator=(const Matrix<T> &m)
	{
		this->N = m.N;
		this->M = m.M;

		values = new T*[N];

		for (int i = 0; i < N; ++i)
		{
			values[i] = new T[M];
		}

		for (int i = 0; i < N*M; ++i)
		{
			values[i / M][i%M] = m.values[i / M][i%M];
		}

		return *this;
	}

	Matrix(const Matrix<T> &m)
	{
		this->N = m.N;
		this->M = m.M;

		values = new T*[N];

		for (int i = 0; i < N; ++i)
		{
			values[i] = new T[M];
		}

		for (int i = 0; i < N*M; ++i)
		{
			values[i / M][i%M] = m.values[i / M][i%M];
		}
	}


	Matrix(int N,int M)
	{
		this->N = N;
		this->M = M;

		values = new T*[N];

		for (int i = 0; i < N; ++i)
		{
			values[i] = new T[M];
		}

		for (int i = 0; i < N*M; ++i)
		{
			values[i / M][i%M] = 0;
		}
	}

	Matrix(int N, int M, T *arr)
	{
		this->N = N;
		this->M = M;

		values = new T*[N];

		for (int i = 0; i < N; ++i)
		{
			values[i] = new T[M];
		}

		for (int i = 0; i < N*M; ++i)
		{
			values[i / M][i%M] = arr[i];
		}
	}

	~Matrix()
	{
        if(values!=NULL)
        {
            for (int i = 0; i < N; ++i)
            {
                delete[] values[i];
            }

            delete[] values;
        }
	}

	Matrix operator*(const Matrix &m)
	{
		if (M != m.N)
		{
			throw MatrixError("Matrices don't have the correct sizes!");
		}
		Matrix<T> r(N, m.M);


		for (int i = 0; i < N; ++i)
		{
			for (int j = 0; j < m.M; ++j)
			{
				for (int k = 0; k < M; ++k)
				{
					r[i][j]+= values[i][k]*m.values[k][j];
				}
			}
		}

		return r;
	}

	Matrix operator*(double v)
	{
		Matrix<T> r(N, M);

		for (int i = 0; i < N; ++i)
		{
			for (int j = 0; j < M; ++j)
			{
				r[i][j] = v*values[i][j];
			}
		}

		return r;
	}

	Matrix operator+(const Matrix &m)
	{
		if (m.N != N && m.M != M)
			throw MatrixError("Sum operator doesn't allow matrices of different sizes");

		Matrix<T> r(N,M);

		for (int i = 0; i < N; ++i)
		{
			for (int j = 0; j < M; ++j)
			{
				r[i][j] = m.values[i][j] + values[i][j];
			}
		}

		return r;
	}

	Matrix operator-(const Matrix &m)
	{
		if (m.N != N && m.M != M)
			throw MatrixError("Sum operator doesn't allow matrices of different sizes");

		Matrix<T> r(N, M);

		for (int i = 0; i < N; ++i)
		{
			for (int j = 0; j < M; ++j)
			{
				r[i][j] = values[i][j] - m.values[i][j];
			}
		}

		return r;
	}

	Matrix t()
	{
		Matrix<T> r(M, N);

		for (int j = 0; j < M; ++j)
		{
			for (int i = 0; i < N; ++i)
			{
				r[j][i] = values[i][j];
			}
		}

		return r;
	}

	T* operator[](int i)
	{
		return values[i];
	}

	friend ostream& operator <<(ostream& o, Matrix<T> &m)
	{
		for (int i = 0; i < m.N; ++i)
		{
			for (int j = 0; j < m.M; ++j)
			{
				o << m[i][j] << " ";
			}

			o << "\n";
		}

		return o;
	}

};



class LinearRegression
{
	double alpha;
	int iterations;

	Matrix<double> params;

public:
	
	LinearRegression(double alpha, int iterations)
	{
		this->alpha = alpha;
		this->iterations = iterations;

	}

	void fit(Matrix<double> &X, Matrix<double> &Y)
	{
	
		params = Matrix<double>(X.M, 1);

		Matrix<double> p;

		
		for(int i=0;i<iterations;++i)
		{
		
			
			params = params - ((X.t()*(X*params - Y)) *(alpha / X.N));

		}

	}

	Matrix<double> getParams()
	{
		return params;
	}

};

int main()
{
	ifstream in("gauss.in");
	ofstream out("gauss.out");

	int N, M;

	in >> N >> M;

	double *arr = new double[N*M];
	double *y = new double[N];

	int q = 0, r = 0;

	for (int i = 0; i < N*(M + 1); ++i)
		if (i % (M+1) == M )
			in >> y[r], ++r;
		else
			in >> arr[q], ++q;
		

	Matrix<double> X(N, M, arr);
	Matrix<double> Y(N, 1, y);



	LinearRegression lr(0.1, 2000);

	try
	{
		lr.fit(X, Y);
	}
	catch (MatrixError &e)
	{
		cout << "Error!";
	}




	Matrix<double> params = lr.getParams();

	for (int i = 0; i < M; ++i)
		out << params[i][0] << " ";

	
	




	return 0;
}