////////////////////////////////////////////////////////////////////// // // Gospodnetic Luka, 0036375942, v1.0, 16.03.2003, // // Implementacija funkcija vezanih uz klasu matrica. Tu se jos // nalaze funkcije koje vrse provjere dimenzija matrica te // provjeru alociranja matrica. // ////////////////////////////////////////////////////////////////////// #include "Matrix.h" ////////////////////////////////////////////////////////////////////// // // Matrix::Matrix() // ---------------- // // Default konstruktor za objekte klase Matrix. // ////////////////////////////////////////////////////////////////////// Matrix::Matrix( void ) : brRedova_ ( 0 ), brStupaca_( 0 ), data_ ( NULL ) {} ////////////////////////////////////////////////////////////////////// // // Matrix::Matrix() // ---------------- // // Copy konstruktor za objekte klase Matrix. // ////////////////////////////////////////////////////////////////////// Matrix::Matrix( const Matrix& src ) : brRedova_ ( 0 ), brStupaca_( 0 ), data_ ( NULL ) { operator=( src ); } ////////////////////////////////////////////////////////////////////// // // Matrix::Matrix() // ---------------- // // Konstruktor koji kreira matricu zadanih dimenzija, // neinicijaliziranog sadrzaja. // ////////////////////////////////////////////////////////////////////// Matrix::Matrix( const int brRedak, const int brStupac ) : brRedova_ ( 0 ), brStupaca_( 0 ), data_ ( NULL ) { if( brRedak < 0 || brStupac < 0 ) throw EInvalidMatrix(); create( brRedak, brStupac ); } ////////////////////////////////////////////////////////////////////// // // Matrix::~Matrix() // // Default destruktor za objekte klase Matrix. // ////////////////////////////////////////////////////////////////////// Matrix::~Matrix( void ) { clear(); } ////////////////////////////////////////////////////////////////////// // // Funkcija check_allocated() // -------------------------- // // Funkcija koja baca exception ukoliko dana matrica nije // inicijalizirana. // ////////////////////////////////////////////////////////////////////// void check_allocated( const Matrix& matrix ) { if ( !matrix.allocated() ) throw ENotAllocated(); } ////////////////////////////////////////////////////////////////////// // // Matrix::check_dimension() // -------------------------------- // // Member funkcija koja vraca true ako su dimenzije matrice jednake // onim dimenzijama koje smo zadali. // ////////////////////////////////////////////////////////////////////// bool Matrix::check_dimension( const int brRedak, const int brStupac ) const { if( getBrojRedova() == brRedak && getBrojStupaca() == brStupac ) return true; return false; } ////////////////////////////////////////////////////////////////////// // // Funkcija check_matrixChained() // ------------------------------ // // Funkcija koja baca exception ukoliko dvije dane matrice nisu // ulancane. // ////////////////////////////////////////////////////////////////////// void check_matrixChained( const Matrix& lhs, const Matrix& rhs ) { check_allocated( lhs ); check_allocated( rhs ); if ( lhs.getBrojStupaca () != rhs.getBrojRedova () ) throw EInvalidMatrix(); } ////////////////////////////////////////////////////////////////////// // // funkcija check_matrixSizeMatch() // -------------------------------- // // Funkcija koja baca exception ukoliko dvije dane matrice nisu // istih dimenzija. // ////////////////////////////////////////////////////////////////////// void check_matrixSizeMatch( const Matrix& lhs, const Matrix& rhs ) { check_allocated( lhs ); check_allocated( rhs ); if ( lhs.getBrojStupaca() != rhs.getBrojStupaca() || lhs.getBrojRedova() != rhs.getBrojRedova() ) throw EInvalidMatrix(); } ////////////////////////////////////////////////////////////////////// // // Matrix::check_quadratic() // -------------------------------- // // Member funkcija koja vraca true ako je matrica kvadratna, inace false. // ////////////////////////////////////////////////////////////////////// bool Matrix::check_quadratic( void ) const { if( getBrojRedova() == getBrojStupaca() ) return true; return false; } ////////////////////////////////////////////////////////////////////// // // Matrix::check_quadratic_dimension() // ----------------------------------- // // Member funkcija koja vraca true ako je matrica kvadratna i dimenzija // je jednaka parametru koji se salje u funkciju. // ////////////////////////////////////////////////////////////////////// bool Matrix::check_quadratic_dimension( const int dimension ) const { if( check_quadratic() && dimension == getBrojRedova() ) return true; return false; } ////////////////////////////////////////////////////////////////////// // // Matrix::clear() // --------------- // // Member funkcija deinicijalizira matricu - oslobadja alociranu // memoriju, postavlja neispravne dimenzije matrice. // ////////////////////////////////////////////////////////////////////// void Matrix::clear() { delete data_; data_ = NULL; brRedova_ = 0; brStupaca_ = 0; } ////////////////////////////////////////////////////////////////////// // // Matrix::create() // ---------------- // // Member funkcija koja (re)kreira matricu zadanih dimenzija. // ////////////////////////////////////////////////////////////////////// void Matrix::create( const int brRedova, const int brStupaca ) { if( brRedova < 0 || brStupaca < 0 ) throw EInvalidMatrix(); clear(); brRedova_ = brRedova; brStupaca_ = brStupaca; data_ = new double[ brRedova * brStupaca ]; } ////////////////////////////////////////////////////////////////////// // // Matrix::getData() // ----------------- // // Member funkcija koja dohvaca vrijednost iz matrice na zadanom retku // i stupcu. // ////////////////////////////////////////////////////////////////////// double Matrix::getData( const int redak, const int stupac ) const { check_allocated( *this ); //moglo bi se napraviti nova funkcija za to..da checkira to..jer se na dva mjesta pojavljuje if( redak < 0 || stupac < 0 || redak >= getBrojRedova() || stupac >= getBrojStupaca() ) throw EInvalidMatrix(); return data_[redak * getBrojStupaca() + stupac]; } ////////////////////////////////////////////////////////////////////// // // funkcija operator>>() // --------------------- // // Operator funkcija koja ucitava matricu sa streama. // ////////////////////////////////////////////////////////////////////// std::istream& operator>>( std::istream& inputStream, Matrix& src ) { if ( !inputStream ) return inputStream; double value; int brStupaca = 0; int brRedova = 0; long pozicija; int t = 0; src.clear(); pozicija = inputStream.tellg(); while (inputStream.peek() != EOF ) { brRedova++; while ( inputStream.peek() != EOF && inputStream.peek() != '\n' ) { inputStream >> value; if( !t ) brStupaca++; } t = 1; if( inputStream.peek() == '\n' ) inputStream.ignore(); } src.create( brRedova, brStupaca ); // makni postavljeni bit....fail ili bad..nekaj od toga... inputStream.clear(); // vrati se na pocetak datoteke inputStream.seekg( pozicija ); brRedova = -1; while (inputStream.peek() != EOF ) { brRedova++; brStupaca = 0; while ( inputStream.peek() != EOF && inputStream.peek() != '\n' ) { inputStream >> value; src.putData( brRedova, brStupaca, value ); brStupaca++; } if( inputStream.peek() == '\n' ) inputStream.ignore(); } inputStream.clear(); inputStream.seekg( pozicija ); return inputStream; } ////////////////////////////////////////////////////////////////////// // // funkcija operator<<() // --------------------- // // Operator funkcija koja ispisuje matricu na stream. // ////////////////////////////////////////////////////////////////////// std::ostream& operator<<( std::ostream& output, const Matrix& m ) { if ( !output ) return output; int i, j; if( m.allocated() == false ) throw ENotAllocated(); for( i = 0; i < m.getBrojRedova(); ++i ) { for( j = 0; j < m.getBrojStupaca(); ++j ) { output << m.getData(i,j); if( j + 1 < m.getBrojStupaca() ) output << ' '; } output << "\n"; } return output; } ////////////////////////////////////////////////////////////////////// // // Matrix::operator+=() // -------------------- // // Member funkcija koja na jednu matricu dodaje drugu. // ////////////////////////////////////////////////////////////////////// Matrix& Matrix::operator+=( const Matrix& rhs ) { check_matrixSizeMatch( *this, rhs ); for( int i = 0; i < getBrojRedova(); ++i ) for( int j = 0; j < getBrojStupaca(); ++j ) putData( i, j, getData(i,j) + rhs.getData(i,j) ); return *this; } ////////////////////////////////////////////////////////////////////// // // Matrix::operator*=() // -------------------- // // Member funkcija koja matricu mnozi skalarom. // ////////////////////////////////////////////////////////////////////// Matrix& Matrix::operator*=( const double skalar ) { check_allocated( *this ); for( int i = 0; i < getBrojRedova(); ++i ) for( int j = 0; j < getBrojStupaca(); ++j ) putData( i, j, getData(i,j)*skalar ); return *this; } ////////////////////////////////////////////////////////////////////// // // Matrix::operator*=() // -------------------- // // Member funkcija koja matricu danom matricom. // ////////////////////////////////////////////////////////////////////// Matrix& Matrix::operator*=( const Matrix& rhs ) { check_matrixChained( *this, rhs ); Matrix tempMatrix( getBrojRedova(), rhs.getBrojStupaca() ); for( int redak(0); redak < getBrojRedova(); ++redak ) { for( int stupac(0); stupac < rhs.getBrojStupaca(); ++stupac ) { double value(0); for( int i(0); i < getBrojStupaca(); ++i ) value += getData(redak,i) * rhs.getData(i,stupac); tempMatrix.putData(redak, stupac, value ); } } swap( tempMatrix ); return *this; } ////////////////////////////////////////////////////////////////////// // // Matrix::operator-=() // -------------------- // // Member funkcija koja od matrice oduzima danu matricu. // ////////////////////////////////////////////////////////////////////// Matrix& Matrix::operator-=( const Matrix& rhs ) { check_matrixSizeMatch( *this, rhs ); for( int i = 0; i < brRedova_; ++i ) for( int j = 0; j < brStupaca_; ++j ) putData( i, j, getData(i,j) - rhs.getData(i,j) ); return *this; } ////////////////////////////////////////////////////////////////////// // // Matrix::operator=() // ------------------- // // Member funkcija koja pridruzuje vrijednost jedne matrice drugoj. // ////////////////////////////////////////////////////////////////////// Matrix& Matrix::operator=( const Matrix& rhs ) { if ( this == &rhs ) return *this; clear(); if ( !rhs.allocated() ) return *this; create( rhs.getBrojRedova(), rhs.getBrojStupaca() ); for( int i = 0; i < getBrojRedova(); ++i ) for( int j = 0; j < getBrojStupaca(); ++j ) putData( i, j, rhs.getData(i,j) ); return *this; } ////////////////////////////////////////////////////////////////////// // // Matrix::operator==() // ------------------- // // Member funkcija koja usporedjuje matrice. Vraca true ako // matrice imaju iste dimenzije te su im vrijednosti iste. // ////////////////////////////////////////////////////////////////////// bool Matrix::operator==( const Matrix& rhs ) const { if( !allocated() || !rhs.allocated() ) return false; if( !check_dimension( rhs.getBrojRedova(), rhs.getBrojStupaca() ) ) return false; for( int i = 0; i < getBrojRedova(); ++i ) for( int j = 0; j < getBrojStupaca(); ++j ) if( getData(i,j) != rhs.getData(i,j) ) return false; return true; } ////////////////////////////////////////////////////////////////////// // // Matrix::putData() // ----------------- // // Member funkcija koja postavlja vrijednost u matricu na zadanom // retku i stupcu. // ////////////////////////////////////////////////////////////////////// void Matrix::putData( const int redak, const int stupac, const double number ) { check_allocated( *this ); //moglo bi se napraviti nova funkcija za to..da checkira to..jer se na dva mjesta pojavljuje if( redak < 0 || stupac < 0 || redak >= getBrojRedova() || stupac >= getBrojStupaca() ) throw EInvalidMatrix(); data_[redak * getBrojStupaca() + stupac] = number; } ////////////////////////////////////////////////////////////////////// // // Matrix::replaceRows() // --------------------- // // Member funkcija koja zamjenjuje vrijednosti dva retka. // ////////////////////////////////////////////////////////////////////// void Matrix::replaceRows( const int row, const int row2 ) { double temp; if( row < 0 || row2 < 0 || row >= getBrojRedova() || row2 >= getBrojRedova()) throw EInvalidMatrix(); for( int stupac = 0; stupac < getBrojStupaca(); ++stupac ) { temp = getData(row, stupac); putData( row, stupac, getData(row2, stupac) ); putData( row2, stupac, temp ); } } ////////////////////////////////////////////////////////////////////// // // Matrix::swap() // -------------- // // Member funkcija koja zamjenjuje vrijednosti dvije matrice. // ////////////////////////////////////////////////////////////////////// void Matrix::swap( Matrix& rhs ) { int tempSize; double* tempData; tempSize = getBrojRedova (); brRedova_ = rhs.getBrojRedova (); rhs.brRedova_ = tempSize; tempSize = getBrojStupaca(); brStupaca_ = rhs.getBrojStupaca(); rhs.brStupaca_ = tempSize; tempData = data_ ; data_ = rhs.data_ ; rhs.data_ = tempData; } ////////////////////////////////////////////////////////////////////// // // Matrix::transpose() // ------------------- // // Member funkcija koja transponira matricu. // ////////////////////////////////////////////////////////////////////// void Matrix::transpose( void ) { check_allocated( *this ); Matrix tempMatrix( getBrojStupaca(), getBrojRedova() ); for( int i = 0; i < getBrojRedova(); ++i ) for( int j = 0; j < getBrojStupaca(); ++j ) tempMatrix.putData(j, i, getData(i,j)); swap( tempMatrix ); }