diff --git a/operator_overloading/Main.cpp b/operator_overloading/Main.cpp index ab75584e1bbe6c91673b32d3a30c968fd44dd800..8ec7b63d09fc1a5ddd8b5e233cf6d5afd385337f 100644 --- a/operator_overloading/Main.cpp +++ b/operator_overloading/Main.cpp @@ -1,11 +1,251 @@ -#include #include "Vector.h" -#include "Matrix.h" - - +#include int main() { - // TODO: Выполнить тестирование + using namespace std; + try + { + cout << "constructor" << endl; + Vector source(2, 5); + cout << source << endl << endl; + // + cout << "operation = " << endl; + Vector vec2(3, 6); + cout << "source =" << source << endl; + cout << "vec2 =" << vec2 << endl; + source = vec2; + cout << "source=vec2 -> source =" << source << endl << endl; + // + cout << "move constructor" << endl; + Vector source1=move(source); + cout << "vec1=source -> vec1 =" << source1 << endl << endl; + // + cout << "operation move = " << endl; + Vector vec1(1, 1); + cout << "vec1 =" << vec1 << endl; + cout << "source1 =" << source1 << endl; + vec1 = move(source1); + cout << "vec1=source1 -> vec1 =" << vec1 << endl << endl; + // + cout << "operation += " << endl; + Vector vec3(3, 8.4); + cout << "vec1 =" << vec1 << endl; + cout << "vec3 =" << vec3 << endl; + vec1 += vec3; + cout << "vec1+=vec3 =" << vec1 << endl << endl; + // + cout << "operation -= " << endl; + cout << "vec2 =" << vec2 << endl; + cout << "vec3 =" << vec3 << endl; + vec2 -= vec3; + cout << "vec2-=vec3 =" << vec2 << endl << endl; + // + cout << "unary - " << endl; + Vector vec4 = -vec1; + cout << "vec1 =" << vec1 << endl; + cout << "vec4= -vec1 -> vec4 =" << vec4 << endl << endl; + // + cout << "unary + " << endl; + Vector vec5 = +vec4; + cout << "vec4 =" << vec1 << endl; + cout << "vec5= +vec4 -> vec5 =" << vec4 << endl << endl; + // + cout << "binary - " << endl; + cout << "vec1 =" << vec1 << endl; + cout << "vec2 =" << vec2 << endl; + cout << "vec1 - vec2 =" << vec1 - vec2 << endl << endl; + // + cout << "binary + " << endl; + cout << "vec1 =" << vec1 << endl; + cout << "vec2 =" << vec2 << endl; + cout << "vec1 + vec2 =" << vec1 + vec2 << endl << endl; + // + cout << "multiplication a vector by a number" << endl; + double number = 3; + cout << "vec1 =" << vec1 << endl; + cout << "scalar =" << number << endl; + cout << "vec1 *scalar =" << vec1 * number << endl << endl; + // + cout << "multiplication a number by a vector" << endl; + number = 5; + cout << "vec1 =" << vec1 << endl; + cout << "scalar =" << number << endl; + cout << "scalar * vec1 =" << number * vec1 << endl << endl; + // + cout << "dot product of vectors" << endl; + cout << "vec1 =" << vec1 << endl; + cout << "vec2 =" << vec2 << endl; + cout << "vec1*vec2 =" << vec1 * vec2 << endl << endl; + // + cout << "input of vector and vector pointer" << endl; + cin >> vec1; + cout << "vec1 =" << vec1 << endl; + double* ptr = (double*)vec1; + cout << "vec1 pointer is " << ptr << endl << endl; + // + cout << "separate element of vector" << endl; + cout << "vec1 =" << vec1 << endl; + cout << "2nd element of vec1 is " << vec1[1] << endl << endl; + // + cout << "method of vector dimension" << endl; + cout << "vec1 =" << vec1 << endl; + cout << "vec1 dimension is " << vec1.dimension() << endl << endl; + // + cout << "method of vector lenghth" << endl; + cout << "vec1 =" << vec1 << endl; + cout << "vec1 lenghth is " << vec1.length() << endl << endl; + // + double* v1 = new double[7]; + v1[0] = 9; + v1[1] = 11; + v1[2] = 10; + v1[3] = 9; + v1[4] = 12; + v1[5] = 8; + v1[6] = 8; + Vector vector(7, 5); + double* v2 = new double[9]; + v2[0] = 1; + v2[1] = 2; + v2[2] = 1; + v2[3] = 2; + v2[4] = 1; + v2[5] = 1; + v2[6] = 2; + v2[7] = 2; + v2[8] = 3; + size_t* v3 = new size_t[9]; + v3[0] = 2; + v3[1] = 1; + v3[2] = 2; + v3[3] = 3; + v3[4] = 1; + v3[5] = 4; + v3[6] = 1; + v3[7] = 2; + v3[8] = 5; + size_t* v4 = new size_t[8]; + v4[0] = 1; + v4[1] = 1; + v4[2] = 1; + v4[3] = 2; + v4[4] = 5; + v4[5] = 7; + v4[6] = 7; + v4[7] = 10; + size_t a = 7; + size_t b = 9; + CSLRMatrix source_m(v1, v2, v3, v4, a, b); + + cout << "source_m:" << endl; + cout << source_m << endl; + // + cout << "move constructor" << endl; + CSLRMatrix mat1 = move(source_m); + cout << "mat1=source_m -> source_m1 =" << mat1 << endl << endl; + // + cout << "multiplication a matrix by a number" << endl; + number = 3; + cout << "scalar =" << number << endl; + cout << "mat1 *scalar =\n" << mat1 * number << endl << endl; + // + cout << "multiplication a number by a matrix" << endl; + number = 5; + cout << "scalar =" << number << endl; + cout << "scalar * mat1 =\n" << number * mat1 << endl << endl; + // + cout << "multiplication a matrix by a vector" << endl; + cout << "vector =" << vector << endl; + cout << "vector * mat1 = " << mat1 * vector << endl << endl; + // + double* ve1 = new double[4]; + ve1[0] = 1; + ve1[1] = 2; + ve1[2] = 3; + ve1[3] = 4; + double* ve2 = new double[2]; + ve2[0] = 2; + ve2[1] = 5; + size_t* ve3 = new size_t[2]; + ve3[0] = 1; + ve3[1] = 2; + size_t* ve4 = new size_t[5]; + ve4[0] = 1; + ve4[1] = 1; + ve4[2] = 1; + ve4[3] = 1; + ve4[4] = 3; + size_t c = 4; + size_t d = 2; + CSLRMatrix mat2(ve1, ve2, ve3, ve4, c, d); + cout << "operation = " << endl; + cout << "mat1 =\n" << mat1 << endl; + cout << "mat2 =\n" << mat2 << endl; + mat2 = mat1; + cout << "mat2=mat1 -> mat2 =\n" << mat2 << endl << endl; + // + cout << "method of matrix size" << endl; + cout << "mat1 dimension is " << mat1.matsize() << endl << endl; + // + cout << "method of matrix's non-zero elements" << endl; + cout << "number of mat1 non-zero elements is " << mat1.nzn() << endl << endl; + // + // + cout << "final test" << endl; + Vector vec(7, 0); + vec[0] = 1; + vec[1] = 2; + vec[2] = 3; + vec[3] = 4; + vec[4] = 5; + vec[5] = 6; + vec[6] = 7; + Vector result(vec); + cout << "vector1 =" << vec << endl; + Vector vect(7, 0); + vect[0] = 14; + vect[1] = 6; + vect[2] = 2; + vect[3] = 11; + vect[4] = 3; + vect[5] = 3; + vect[6] = 1; + cout << "vector2 =" << vect << endl; + Vector vecto(7, 0); + vecto[0] = 5; + vecto[1] = 6; + vecto[2] = 4; + vecto[3] = 19; + vecto[4] = 6; + vecto[5] = 20; + vecto[6] = 5; + cout << "vector3 =" << vecto << endl; + int k1 = 4; + cout << "number1 =" << a << endl; + int k2 = 10; + cout << "number2 =" << b << endl; + int k3 = 10; + cout << "number3 =" << c << endl; + cout << "matrix =" << endl << mat1 << endl; + result = -k1 * mat1 * (vec - k2 * vect) + vecto * k3; + cout << " result = -number1 * matrix * (vector1 - number2 * vector2) + vector3 * number3" << endl << result << endl; + delete[] v1; + delete[] v2; + delete[] v3; + delete[] v4; + delete[] ve1; + delete[] ve2; + delete[] ve3; + delete[] ve4; + } + catch (OutOfRangeException& exception) + { + std::cout << exception.what(); + } + catch (IncompatibleDimException& exception) + { + std::cout << exception.what(); + } return 0; } \ No newline at end of file diff --git a/operator_overloading/Matrix.cpp b/operator_overloading/Matrix.cpp index 569f06b74380b358f0bc25d806dd89f59bad9510..39e4c55edb7a705f38d17e0c06b974f854047d88 100644 --- a/operator_overloading/Matrix.cpp +++ b/operator_overloading/Matrix.cpp @@ -1 +1,245 @@ -#include "Matrix.h" +#include +#include "exception.h" +#include "Vector.h" +#include +using namespace std; + + +CSLRMatrix::CSLRMatrix(double* p_adiag, double* p_altr, size_t* p_jptr, size_t* p_iptr, size_t p_diag, size_t p_elem) : + m_adiag(new double[p_diag]), + m_diag(p_diag), + m_altr(new double[p_elem]), + m_elem(p_elem), + m_jptr(new size_t[p_elem]), + m_iptr(new size_t[p_diag + 1]) +{ + for (int i = 0; i < p_diag; ++i) + { + m_adiag[i] = p_adiag[i]; + } + for (int i = 0; i < p_elem; ++i) + { + m_altr[i] = p_altr[i]; + m_jptr[i] = p_jptr[i]; + } + for (int i = 0; i < p_diag + 1; ++i) + { + m_iptr[i] = p_iptr[i]; + } +} + + +CSLRMatrix::CSLRMatrix(const CSLRMatrix& p_mat) : + m_adiag(new double[p_mat.m_diag]), + m_diag(p_mat.m_diag), + m_altr(new double[p_mat.m_elem]), + m_elem(p_mat.m_elem), + m_jptr(new size_t[p_mat.m_elem]), + m_iptr(new size_t[p_mat.m_diag + 1]) +{ + for (int i = 0; i < p_mat.m_diag; ++i) + { + m_adiag[i] = p_mat.m_adiag[i]; + } + for (int i = 0; i < p_mat.m_elem; ++i) + { + m_altr[i] = p_mat.m_altr[i]; + m_jptr[i] = p_mat.m_jptr[i]; + } + for (int i = 0; i < p_mat.m_diag + 1; ++i) + { + m_iptr[i] = p_mat.m_iptr[i]; + } +} + + +CSLRMatrix::CSLRMatrix(CSLRMatrix&& p_mat) : + m_adiag(p_mat.m_adiag), + m_diag(p_mat.m_diag), + m_altr(p_mat.m_altr), + m_elem(p_mat.m_elem), + m_jptr(p_mat.m_jptr), + m_iptr(p_mat.m_iptr) +{ + p_mat.m_adiag = nullptr; + p_mat.m_altr = nullptr; + p_mat.m_jptr = nullptr; + p_mat.m_iptr = nullptr; + p_mat.m_diag = 0; + p_mat.m_elem = 0; +} + + +CSLRMatrix::~CSLRMatrix() { + delete[] m_adiag; + delete[] m_altr; + delete[] m_iptr; + delete[] m_jptr; +} + + +std::istream& operator>>(std::istream& p_is, CSLRMatrix& p_mat) { + + printf("\nenter the elements that are on the main diagonal\n"); + for (int i = 0; i < p_mat.m_diag; i++) + p_is >> p_mat.m_adiag[i]; + printf("\nenter nonzero matrix elements\n"); + for (int i = 0; i < p_mat.m_elem; i++) + p_is >> p_mat.m_altr[i]; + printf("\nin which columns are these elements\n"); + for (int i = 0; i < p_mat.m_elem; i++) + p_is >> p_mat.m_jptr[i]; + printf("\nWith what position in the array of all non - zero elements does the i-th line begin matrices\n"); + for (int i = 0; i < p_mat.m_diag+1; i++) + p_is >> p_mat.m_iptr[i]; + return p_is; +} + + +std::ostream& operator<<(std::ostream& p_os, const CSLRMatrix& p_mat) { + for (int i = 0; i < p_mat.m_diag; i++) { + for (int j = 0; j < p_mat.m_diag; j++) { + double val = 0; + if (i == j) + { + val = p_mat.m_adiag[i]; + } + else + { + for (int k = p_mat.m_iptr[i] - 1; k < p_mat.m_iptr[i + 1] - 1; k++) { + if (p_mat.m_jptr[k] - 1 == j) { + val = p_mat.m_altr[k]; + break; + } + } + for (int k = p_mat.m_iptr[j] - 1; k < p_mat.m_iptr[j + 1] - 1; k++) { + if (p_mat.m_jptr[k] - 1 == i) { + val = p_mat.m_altr[k]; + break; + } + } + } + p_os << setw(4) << val; + } + p_os << std::endl << std::endl; + } + return p_os; +} + + +size_t CSLRMatrix::matsize() const +{ + return m_diag; +} + + +size_t CSLRMatrix::nzn() const +{ + int ans = m_elem * 2; + for (int i = 0; i < m_diag; i++) + { + if (m_adiag[i] != 0) ans++; + } + return ans; +} + + +const CSLRMatrix& CSLRMatrix::operator=(const CSLRMatrix& p_mat) +{ + if (this == &p_mat) + { + return *this; + } + if (m_diag != p_mat.m_diag) + { + delete[] m_adiag; + delete[] m_altr; + delete[] m_jptr; + delete[] m_iptr; + m_adiag = new double[p_mat.m_diag]; + m_altr = new double[p_mat.m_elem]; + m_jptr = new size_t[p_mat.m_elem]; + m_iptr = new size_t[p_mat.m_diag+ 1]; + m_diag = p_mat.m_diag; + m_elem = p_mat.m_elem; + } + for (int i = 0; i < p_mat.m_diag; ++i) + { + m_adiag[i] = p_mat.m_adiag[i]; + } + for (int i = 0; i < p_mat.m_elem; ++i) + { + m_altr[i] = p_mat.m_altr[i]; + m_jptr[i] = p_mat.m_jptr[i]; + } + for (int i = 0; i < p_mat.m_diag + 1; ++i) + { + m_iptr[i] = p_mat.m_iptr[i]; + } + return *this; +} + + +CSLRMatrix& CSLRMatrix::operator=(CSLRMatrix&& p_mat) +{ + delete[] m_adiag; + delete[] m_altr; + delete[] m_jptr; + delete[] m_iptr; + m_adiag = p_mat.m_adiag; + m_altr = p_mat.m_altr; + m_jptr = p_mat.m_jptr; + m_iptr = p_mat.m_iptr; + m_diag = p_mat.m_diag; + m_elem = p_mat.m_elem; + p_mat.m_adiag = nullptr; + p_mat.m_altr = nullptr; + p_mat.m_jptr = nullptr; + p_mat.m_iptr = nullptr; + p_mat.m_diag = 0; + p_mat.m_elem = 0; + return *this; +} + +Vector operator*(const CSLRMatrix& p_mat, const Vector& p_vec) +{ + if (p_mat.matsize() != p_vec.dimension()) + { + throw IncompatibleDimException{}; + } + Vector res(p_vec); + for (int i = 0; i < p_mat.matsize(); i++) + { + res[i] = p_vec[i] * p_mat.m_adiag[i]; + } + for (int i = 0; i < p_mat.matsize(); i++) + { + for (int j = p_mat.m_iptr[i] - 1; j < p_mat.m_iptr[i + 1] - 1; j++) + { + res[i] += p_vec[p_mat.m_jptr[j] - 1] * p_mat.m_altr[j]; + res[p_mat.m_jptr[j] - 1] += p_vec[i] * p_mat.m_altr[j]; + } + } + return res; +} + + +CSLRMatrix operator*(const CSLRMatrix& p_mat, double p_scalar) +{ + CSLRMatrix result(p_mat); + for (int i = 0; i +#include "exception.h" +#include +#include "Vector.h" +class Vector; +class CSLRMatrix { +private: -// TODO: Выбрать класс в соответствии с вариантом + double* m_adiag; + double* m_altr; + size_t* m_jptr; + size_t* m_iptr; + size_t m_diag; + size_t m_elem; + friend class Vector; +public: -//class CSRMatrix -//{ -//public: -// -//}; + CSLRMatrix(double* p_adiag, double* p_altr, size_t* p_jptr, size_t* p_iptr, size_t p_diag, size_t p_elem); + CSLRMatrix(const CSLRMatrix& p_mat); + ~CSLRMatrix(); + CSLRMatrix(CSLRMatrix&& p_mat); -//class CSLRMatrix -//{ -//public: -// -//}; \ No newline at end of file + friend std::istream& operator>>(std::istream& p_is, CSLRMatrix& p_mat); + friend std::ostream& operator<<(std::ostream& p_os, const CSLRMatrix& p_mat); + + size_t matsize() const; + size_t nzn() const; + + const CSLRMatrix& operator=(const CSLRMatrix& p_mat); + CSLRMatrix& operator=(CSLRMatrix&& p_mat); + + friend Vector operator*(const CSLRMatrix& p_mat, const Vector& p_vec); + friend CSLRMatrix operator*(double p_scalar, const CSLRMatrix& p_mat); + friend CSLRMatrix operator*(const CSLRMatrix& p_mat, double p_scalar); +}; \ No newline at end of file diff --git a/operator_overloading/Vector.cpp b/operator_overloading/Vector.cpp index c29aab752922849e849325dc01558740d54a72be..d37fbfb0adea705f5d2e72b06962fb70b4e51596 100644 --- a/operator_overloading/Vector.cpp +++ b/operator_overloading/Vector.cpp @@ -1,2 +1,196 @@ +#include +#include "exception.h" +#include #include "Vector.h" +#include "Matrix.h" + +Vector::Vector(int p_n, double p_value) { + m_size = p_n; + m_data = new double[m_size]; + for (int i = 0; i < m_size; i++) { + m_data[i] = p_value; + } +} + + +Vector::Vector(const Vector& p_vec): + m_size ( p_vec.m_size), + m_data ( new double[m_size]) +{ + + for (int i = 0; i < m_size; i++) { + m_data[i] = p_vec.m_data[i]; + } +} + + +Vector::Vector(Vector&& p_vec): + m_size(p_vec.m_size), + m_data(p_vec.m_data) +{ + p_vec.m_data = nullptr; + p_vec.m_size = 0; +} + + +Vector::~Vector() { + delete[] m_data; +} + + +Vector& Vector:: operator=(const Vector& p_vec) { + if (this != &p_vec) { + delete[] m_data; + m_size = p_vec.m_size; + m_data = new double[m_size]; + for (int i = 0; i < m_size; i++) { + m_data[i] = p_vec.m_data[i]; + } + } + return *this; +} + + +Vector& Vector:: operator=(Vector&& p_vec) { + delete[] m_data; + m_size = p_vec.m_size; + m_data = p_vec.m_data; + p_vec.m_data = nullptr; + p_vec.m_size = 0; + return *this; +} + + +Vector& Vector::operator+=(const Vector& p_vec) { + if (m_size != p_vec.m_size) { + throw IncompatibleDimException(); + } + for (int i = 0; i < m_size; i++) { + m_data[i] += p_vec.m_data[i]; + } + return *this; +} + + +Vector& Vector::operator-=(const Vector& p_vec) { + if (m_size != p_vec.m_size) { + throw IncompatibleDimException(); + } + for (int i = 0; i < m_size; i++) { + m_data[i] -= p_vec.m_data[i]; + } + return *this; +} + + +Vector Vector::operator+() const { + return *this; +} + + +Vector Vector::operator-() const { + Vector result(m_size); + for (int i = 0; i < m_size; i++) { + result.m_data[i] = -m_data[i]; + } + return result; +} + + +Vector operator+(const Vector& p_vec_1, const Vector& p_vec_2) { + if (p_vec_1.m_size != p_vec_2.m_size) { + throw IncompatibleDimException(); + } + Vector result(p_vec_1); + result += p_vec_2; + return result; +} + + +Vector operator-(const Vector& p_vec_1, const Vector& p_vec_2) { + if (p_vec_1.m_size != p_vec_2.m_size) { + throw IncompatibleDimException(); + } + Vector result(p_vec_1); + result -= p_vec_2; + return result; +} + + +double operator*(const Vector& p_vec_1, const Vector& p_vec_2) { + double result = 0.0; + for (int i = 0; i < p_vec_1.m_size; i++) { + result += p_vec_1.m_data[i] * p_vec_2.m_data[i]; + } + return result; +} + +Vector operator*(const Vector& p_vec, double p_scalar) { + Vector result(p_vec); + for (int i = 0; i < p_vec.m_size; i++) { + result.m_data[i] *= p_scalar; + } + return result; +} + + +Vector operator*(double p_scalar, const Vector& p_vec) { + return p_vec * p_scalar; +} + + +double& Vector::operator[](int p_index) { + if (p_index < 0 || p_index >= m_size) { + throw OutOfRangeException(); + } + return m_data[p_index]; +} + + +const double& Vector::operator[](int p_index) const { + if (p_index < 0 || p_index >= m_size) { + throw OutOfRangeException(); + } + return m_data[p_index]; +} + + +std::ostream& operator<<(std::ostream& p_os, const Vector& p_vec) { + p_os << "["; + for (int i = 0; i < p_vec.m_size; i++) { + p_os << p_vec.m_data[i]; + if (i < p_vec.m_size - 1) { + p_os << ", "; + } + } + p_os << "]"; + return p_os; +} + + +std::istream& operator>>(std::istream& p_is, Vector& p_vec) { + for (int i = 0; i < p_vec.m_size; i++) { + p_is >> p_vec.m_data[i]; + } + return p_is; +} + + +Vector:: operator double* () { + return m_data; +} + + +double Vector::length() const { + double result = 0.0; + for (int i = 0; i < m_size; i++) { + result += m_data[i] * m_data[i]; + } + return sqrt(result); +} + + +int Vector::dimension() const { + return m_size; +} \ No newline at end of file diff --git a/operator_overloading/Vector.h b/operator_overloading/Vector.h index 3f6a4a4ed7822dde3013a16bd2176fb9746e6195..639b8448903ea538da6b970cb5798319038175f1 100644 --- a/operator_overloading/Vector.h +++ b/operator_overloading/Vector.h @@ -1,9 +1,58 @@ #pragma once - - +#include +#include +#include +#include "Matrix.h" +class CSLRMatrix; class Vector { + public: + explicit Vector(int p_n = 0, double p_value = 0.0); + + Vector(const Vector& p_vec); + + ~Vector(); + + Vector(Vector&& p_vec); + + double& operator[](int p_index); + + const double& operator[](int p_index) const; + + Vector& operator=(const Vector& p_vec); + Vector& operator=(Vector&& p_vec); + + Vector& operator+=(const Vector& p_vec); + Vector& operator-=(const Vector& p_vec); + + Vector operator+() const; + Vector operator-() const; + + friend Vector operator+(const Vector& p_vec_1, const Vector& p_vec_2); + friend Vector operator-(const Vector& p_vec_1, const Vector& p_vec_2); + + friend double operator*(const Vector& p_vec_1, const Vector& p_vec_2); + friend Vector operator*(const Vector& p_vec, double p_scalar); + friend Vector operator*(double p_scalar, const Vector& p_vec); + + friend std::ostream& operator<<(std::ostream& p_os, const Vector& p_vec); + friend std::istream& operator>>(std::istream& p_is, Vector& p_vec); + + explicit operator double* (); + + double length() const; + int dimension() const; + +private: + int m_size; + double* m_data; + friend class CSLRMatrix; }; + + + + + diff --git a/operator_overloading/exception.cpp b/operator_overloading/exception.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a542fae3c19b34ce275d3521d2f076d50d888ca --- /dev/null +++ b/operator_overloading/exception.cpp @@ -0,0 +1,14 @@ +#include +#include "exception.h" + + +const char* OutOfRangeException::what() const +{ + return "Index is out of range"; +} + + +const char* IncompatibleDimException::what() const +{ + return "Vectors have incompatible dimensions"; +} \ No newline at end of file diff --git a/operator_overloading/exception.h b/operator_overloading/exception.h new file mode 100644 index 0000000000000000000000000000000000000000..b11e282916f2211b7ad98f0e81e9a3eac794fcf9 --- /dev/null +++ b/operator_overloading/exception.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include +#include + + +class OutOfRangeException : public std::exception +{ +public: + const char* what() const override; +}; + + +class IncompatibleDimException : public std::exception +{ +public: + const char* what() const override; +}; \ No newline at end of file