// Matrice.h #pragma once #include #include #include using namespace std; template class Matrice { private: int ordin; vector> elemente; Matrice getMinor(int, int); void interschimbareLinii(int, int, int); void multiplicareLinie(int, int, T); void operatieLinii(int, int, int, T); int liberColoana(int, int, int); public: Matrice() : Matrice(0) {} Matrice(int); Matrice(const Matrice&); ~Matrice(); friend istream& operator >>(istream& in, Matrice& M) { for (int i = 0; i < M.ordin; ++i) for (int j = 0; j < M.ordin; ++j) in >> M[i][j]; return in; } friend ostream& operator <<(ostream& out, Matrice M) { for (int i = 0; i < M.ordin; ++i, out << endl) for (int j = 0; j < M.ordin; ++j) out << setw(10) << M[i][j] << ' '; return out; } vector& operator[](int indexLinie) { return elemente[indexLinie]; } Matrice& operator =(const Matrice&); bool operator ==(const Matrice& A) { if (ordin != A.ordin) return false; for (int i = 0; i < ordin; ++i) for (int j = 0; j < ordin; ++j) if (elemente[i][j] != A.elemente[i][j]) return false; return true; } bool operator !=(const Matrice& A) { if (ordin != A.ordin) return true; int nrElemEgale = 0; for (int i = 0; i < ordin; ++i) for (int j = 0; j < ordin; ++j) if (elemente[i][j] == A.elemente[i][j]) nrElemEgale++; if (nrElemEgale == ordin * ordin) return false; return true; } Matrice operator +(Matrice); Matrice operator -(Matrice); Matrice operator *(Matrice); Matrice operator *(T); Matrice& operator += (const Matrice&); Matrice& operator -= (const Matrice&); Matrice& operator *= (const Matrice&); Matrice operator^(int); Matrice getTranspusa(); T operator !(); Matrice getInversa(); }; template Matrice::Matrice(int ordin) : ordin(ordin) { elemente.resize(ordin); for (int i = 0; i < ordin; ++i) for (int j = 0; j < ordin; ++j) elemente[i].push_back(0); } template Matrice::Matrice(const Matrice& M) { ordin = M.ordin; elemente.resize(ordin); for (int i = 0; i < ordin; ++i) for (int j = 0; j < ordin; ++j) elemente[i].push_back(M.elemente[i][j]); } template Matrice::~Matrice() { elemente.clear(); elemente.shrink_to_fit(); } template Matrice& Matrice::operator=(const Matrice& M) { if (this != &M) { this->~Matrice(); ordin = M.ordin; elemente.resize(ordin); for (int i = 0; i < M.ordin; ++i) for (int j = 0; j < M.ordin; ++j) elemente[i].push_back(M.elemente[i][j]); } return *this; } template Matrice Matrice::operator+(Matrice M) { Matrice Suma(M.ordin); for (int i = 0; i < M.ordin; ++i) for (int j = 0; j < M.ordin; ++j) Suma[i][j] = elemente[i][j] + M[i][j]; return Suma; } template Matrice Matrice::operator-(Matrice M) { Matrice Diferenta(M.ordin); for (int i = 0; i < M.ordin; ++i) for (int j = 0; j < M.ordin; ++j) Diferenta[i][j] = elemente[i][j] - M[i][j]; return Diferenta; } template Matrice Matrice::operator*(Matrice M) { Matrice Produs(ordin); for (int i = 0; i < ordin; ++i) for (int j = 0; j < M.ordin; ++j) for (int k = 0; k < ordin; ++k) Produs[i][j] += elemente[i][k] * M[k][j]; return Produs; } template Matrice Matrice::operator*(T scalar) { Matrice Produs(ordin); for (int i = 0; i < ordin; ++i) for (int j = 0; j < ordin; ++j) Produs[i][j] = elemente[i][j] * scalar; return Produs; } template Matrice& Matrice::operator+=(const Matrice& M) { *this = *this + M; return *this; } template Matrice& Matrice::operator-=(const Matrice& M) { *this = *this - M; return *this; } template Matrice& Matrice::operator*=(const Matrice& M) { *this = *this * M; return *this; } template Matrice Matrice::operator^(int putere) { Matrice matr(*this); if (putere == 0) return matr * matr.getInversa(); for (int i = 1; i < putere; ++i) matr *= *this; return matr; } template Matrice Matrice::getTranspusa() { Matrice transp(*this); for (int i = 0; i < ordin; ++i) for (int j = 0; j < ordin; ++j) transp.elemente[i][j] = elemente[j][i]; return transp; } template Matrice Matrice::getMinor(int linie, int coloana) { Matrice minor(ordin - 1); int nr = 0; for (int i = 0; i < ordin; ++i) for (int j = 0; j < ordin; ++j) if (i != linie && j != coloana) { minor[nr / (ordin - 1)][nr % (ordin - 1)] = elemente[i][j]; nr++; } return minor; } template T Matrice::operator!() { if (ordin == 1) return elemente[0][0]; if (ordin == 2) return elemente[0][0] * elemente[1][1] - elemente[0][1] * elemente[1][0]; float suma = 0; int semn = 1; for (int j = 0; j < ordin; ++j) { Matrice minor = this->getMinor(0, j); suma += elemente[0][j] * (!minor) * semn; semn = -semn; } return suma; } template void Matrice::multiplicareLinie(int nrC, int linie, T a) // M_i(a) sau L_i -> a*L_i { for (int i = 0; i < nrC; ++i) elemente[linie][i] = elemente[linie][i] * a; } template void Matrice::interschimbareLinii(int nrC, int linie1, int linie2) //S_ij sau L_i <-> L_j { for (int i = 0; i < nrC; ++i) std::swap(elemente[linie1][i], elemente[linie2][i]); } template void Matrice::operatieLinii(int nrC, int linie1, int linie2, T a) //T_i(a*L_j) sau L_i -> a*L_j + L_i { for (int j = 0; j < nrC; ++j) if ((T)(elemente[linie1][j] - a * elemente[linie2][j]) < (T)0.000001 && (T)(elemente[linie1][j] - a * elemente[linie2][j]) > (T)-0.000001) elemente[linie1][j] = 0; else elemente[linie1][j] = elemente[linie1][j] - a * elemente[linie2][j]; } template int Matrice::liberColoana(int nrL, int linie, int coloana) { for (int i = linie; i < nrL; ++i) if (elemente[i][coloana] != 0) return i; return -1; } template Matrice Matrice::getInversa() // Metoda Jordan-Gauss { Matrice mat(*this); for (int i = 0; i < ordin; i++) for (int j = 0; j < ordin; j++) if (i == j) mat[i].push_back(1); else mat[i].push_back(0); int contorLinie = 0, contorColoana = 0; while (contorLinie < ordin && contorColoana < ordin) { if (mat[contorLinie][contorColoana] != 1 && mat[contorLinie][contorColoana] != 0) mat.multiplicareLinie(2 * ordin, contorLinie, 1 / mat[contorLinie][contorColoana]); else if (mat[contorLinie][contorColoana] == 0) { int indiceLinie = mat.liberColoana(ordin, contorLinie, contorColoana); if (indiceLinie != -1) mat.interschimbareLinii(2 * ordin, contorLinie, indiceLinie); else contorColoana++; } else if (mat[contorLinie][contorColoana] == 1) { for (int i = 0; i < ordin; i++) if (i != contorLinie && mat[i][contorColoana] != 0) mat.operatieLinii(2 * ordin, i, contorLinie, mat[i][contorColoana]); contorLinie++; contorColoana++; } } Matrice inversa(ordin); for (int i = 0; i < ordin; ++i) for (int j = ordin; j < 2 * ordin; ++j) { if (mat[i][j] == -0) mat[i][j] = 0; inversa[i][j - ordin] = mat[i][j]; } return inversa; } // Matrice.cpp #include "Matrice.h" template Matrice suma(Matrice A, int ordin, int putere) { Matrice tA = A.getTranspusa(), Suma(ordin); for (int i = 1; i <= putere; ++i) { Suma += (tA ^ i); cout << "(tA)^" << i; if (i < putere) cout << " + "; else cout << " = " << endl; } return Suma; } int main() { int putere, ordin; cout << "Introduceti ordinul matricei : "; cin >> ordin; Matrice A(ordin); cout << "Introduceti matricea : \n"; cin >> A; cout << "Introduceti puterea : "; cin >> putere; cout << suma(A, ordin, putere) << endl; cout << "Determinantul matricei A : " << (!A) << endl; if (!A != 0) cout << "Inversa matricei A : \n" << A.getInversa(); else cout << "Matricea nu este inversabila. \n"; return 0; }