Pagini recente » Cod sursa (job #2476706) | Cod sursa (job #822062) | Cod sursa (job #2104726) | Cod sursa (job #1581534) | Cod sursa (job #2419324)
#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()
{
}
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.01, 2000);
try
{
lr.fit(X, Y);
}
catch (MatrixError &e)
{
cout << "Error!";
}
Matrix<double> params = lr.getParams();
for (int i = 0; i < N; ++i)
out << params[i][0] << " ";
return 0;
}