Termín odevzdání | 22.5.2022 23:59 CEST |
---|---|
Možný bodový zisk | až 9b (3+3+3) |
Počet uploadů | 10 |
Napište modul, který bude definovat strukturu matic a bude s nimi provádět různé operace.
Matice musí uchovány v instancích objektů třídy Matrix
. Část struktury třídy “Matrix” a rozhraní funkcí určených k implementaci je předem dané. Součástí zadání jsou 3 soubory zdrojových kódů:
main.cpp
- kód hlavního programu, který využívá (testuje) jednotlivé funkce, jež májí být implementovány. Tento soubor se neodevzdává, nemusíte ho tedy nijak upravovat. Využijte ho pouze k testování vašich zdrojových kódů.
matrix.hpp
- hlavičkový soubor knihovny. Obsahuje povinnou část třídy Matrix
a deklaraci funkcí, které je třeba implementovat. Tento soubor lze upravit, nicméně rozhraní funkcí musí být zachováno tak, jak je. Můžete ovšem přidávat deklarace vašich funkcí, případně si vylepšit třídu Matrix
. Soubor rovněž definuje výjimky, které by vaše funkce měly vyvolávat, při špatném zadání.
matrix.cpp
- zdrojový kód knihovny. Zatím obsahuje pouze prázdné funkce. Vaším úkolem je doplnit těla funkcí tak, aby celý program korektně fungoval.
Testování probíhá ve dvou úrovních, označovaných L1 a L2, pro každou z úrovní je třeba naprogramovat některé z funkcí uvedených v hlavičkovém souboru matrix.hpp
. V komentářích hlavičkového souboru je uvedeno, do které úrovně funkce patří.
Úroveň L1 je ohodnocena 3 body, úroveň L2 ohodnocena taktéž 3 body. Obě úrovně je potřeba splnit.
Třída Matrix
musí obsahovat proměnné s viditelností public
:
nrows | počet řádků matice, může nabývat hodnot nrows>=0 |
---|---|
ncols | počet sloupců matice , může nabývat hodnot ncols>=0 |
Data matice uchovejte v libovolné vhodné formě. Je výhodné využít knihovnu standadních šablon.
Třída Matrix
definovat následující konstruktory:
Matrix(int rows, int cols); | Vytvoří matici o počtu řádků rows a počtu sloupců cols naplněnou nulami. |
---|---|
Matrix(int rowscols=0); | Vytvoří čtvercovou matici o velikosti rowscols naplněnou nulami. Výchozí hodnotou je matice o velikosti 0x0 . |
Matrix(const Matrix &m); | Kopírující konstruktor. |
matrix_negative_size
.
Matrix
Pro jednotlivé úrovně testování je třeba implementovat následující funkce a operátory třídy Matrix:
Úroveň L1 | ||
---|---|---|
Funkce/Operátor | Popis | Výjimky |
void Matrix::zeros() | Nastaví všechny prvky dané matice na hodnotu 0 . | Žádné |
void Matrix::uniform(value element) | Nastaví všechny prvky dané matice na hodnotu element . | Žádné |
void Matrix::eye() | Vytvoří matici identity - prvky na hlavní diagonále mají hodnotu 1 , ostatní hodnotu 0 . Pokud není matice čtvercová, doplní se zbytek nulami. | Žádné |
void Matrix::bias(value b) | Pričte ke každému prvku matice hodnotu b . | Žádné |
bool operator == (const Matrix & m) | Operátor porovnání dvou matic. Vrací true pouze při shodě rozměrů matic i všech prvků. | Žádné |
Matrix & operator=(const Matrix &m) | Operator přiřazení celé matice. | Žádné |
value Matrix::operator () (int row, int col) const | Náhodný přístup - čtení. Vrací prvek matice na řádku 'row' a ve sloupci 'col' (indexováno od nuly). | std::out_of_range(“Row index is out of range”) , při překročení šířky matice, std::out_of_range(“Column index is out of range”) při překročení výšky matice. Při překročení obou rozměrů dochází k vyvolání první z výjimek. |
value & Matrix::operator () (int row, int col) | Náhodný přístup - zápis. Vrací adresu prvku matice na řádku 'row' a ve sloupci 'col' (indexováno od nuly). | std::out_of_range(“Row index is out of range”) , při překročení šířky matice, std::out_of_range(“Column index is out of range”) při překročení výšky matice. Při překročení obou rozměrů dochází k vyvolání první z výjimek. |
Úroveň L2 | ||
Funkce/Operátor | Popis | Výjimky |
void Matrix::scale(value s) | Vynásobí každý prvek matice hodnotou s . | Žádné |
void Matrix::transpose() | Transponuje matici. | Žádné |
Pro jednotlivé úrovně testování je třeba implementovat následující funkce a operátory mimo třídu Matrix:
Úroveň L1 | ||
---|---|---|
Funkce/Operátor | Popis | Výjimky |
std::ostream & operator « (std::ostream & os, const Matrix & m) | Výpis matice m do výstupního proudu. Vypisují se jednotlivé prvky matice po řádcích. Pro každou hodnotu je rezervováno 5 míst, za každým číslem je mezera (i na konci řádku). Na konci matice je newline. Pokud matice neobsahuje žádný prvek (nějaký z rozměrů je nulový), vypíše se pouze std::endl | Žádné |
void loadMatrixFile(Matrix &m, std::string fname) | Načtení matice m ze souboru se jménem fname . Formát souboru matice je definován níže. | |
Matrix operator + (const Matrix & lhs, const Matrix & rhs) | Součet dvou matic se stejnými rozměry. | matrix_bad_sizes při neshodě rozměrů matic. |
Matrix operator + (const value & lhs, const Matrix & rhs) | Přičtení skaláru ke každému prvku matice. | Žádné |
Matrix operator + (const Matrix & lhs, const value & rhs) |
||
Matrix operator - (const Matrix & lhs, const Matrix & rhs) | Rozdíl dvou matic se stejnými rozměry. | matrix_bad_sizes při neshodě rozměrů matic. |
Matrix operator - (const value & lhs, const Matrix & rhs) | Odečtení matice od skaláru (rozdíl pro každý prvek). | Žádné |
Matrix operator - (const Matrix & lhs, const value & rhs) | Odečtení skaláru od matice (rozdíl pro každý prvek). | Žádné |
Úroveň L2 | ||
Funkce/Operátor | Popis | Výjimky |
Matrix operator * (const Matrix & lhs, const Matrix & rhs) | Součin dvou matic. | matrix_bad_sizes při nevhodných rozměrech. |
Matrix operator * (const value & lhs, const Matrix & rhs) | Součin matice a skaláru. | matrix_bad_sizes při nevhodných rozměrech. |
Matrix operator * (const Matrix & lhs, const value & rhs) |
||
Matrix hadamard (const Matrix & lhs, const Matrix & rhs) | Hadamardův součin - prvek po prvku (ekvivalent .* z Matlabu) | matrix_bad_sizes při neshodě rozměrů matic. |
Matrix power (const Matrix & m, unsigned int pow) | Kladná mocnina čtvercové matice: power(A, 3) je ekvivalent A*A*A . | matrix_bad_sizes při špatném rozměru matice |
0x5
a 5×0
je matice rozměru 0x0
matrix.hpp
nemažte deklarace funkcí, které nechcete nebo nemusíte implementovat (např. funkce úrovně L3)! Pokud smažete tyto deklarace, nebude možné zkompilovat main.cpp
. Funkce, které neimplementujte, musí vracet návratovou hodnotu odpovídajícího datového typu (i když jinak nic nedělají).
Výjimky, které mají být vyvolány jsou v matrix.hpp
definovány následovně:
// Vyjimka pri spatnych rozmerech matice pro danou operaci: struct matrix_bad_sizes: public std::exception {const char * what () const throw (){return "matrix_bad_sizes";}}; // Vyjimka pri zadani negativniho rozmeru struct matrix_negative_size: public std::exception {const char * what () const throw (){return "matrix_negative_size";}}; // Vyjimka pri chybe nacteni rozmeru matice struct matrix_in_bad_header: public std::exception {const char * what () const throw (){return "matrix_in_bad_header";}}; // Vyjimka pri chybe nacteni prvku matice struct matrix_in_bad_body: public std::exception {const char * what () const throw (){return "matrix_in_bad_body";}}; // Vyjimka pri otevirani souboru matice struct cannot_open_file: public std::exception {const char * what () const throw (){return "cannot_open_file";}};
Program bude zavolán příkazem ./main -l1
nebo ./main -l2
. Samotný program 'main' poté provádí řadu testů funkcí modulu 'matrix', který naprogramujete.
V průběhu se program pokusí načíst několik matic ze souborů.
Formát souboru matice je následující:
* Na prvním řádku jsou dvě čísla - počet řádků a počet sloupců. * Na dalších řádcích jsou po řádcích hodnoty prvků matice oddělené mezerami.
Příklad obsahu souboru matice:
4 6 -54 -36 -37 -49 59 -33 -80 57 -93 -36 94 24 -48 -45 -55 -48 -98 -68 28 24 -31 -83 -89 75
Při načítání soubodu musí být vyvolána výjimka když:
* když je chyba v řádku hlavičky - chybí číslo, nebo se tam objeví písmeno. * když chybí data - nějaký řádek je příliš krátký, nebo úplně chybí. * když se mezi data zatoulá písmeno
Nemusíte kontrolovat, zdanení řádek příliš dlouhý, nebo jestli nepřebývají řádky. Data navíc se ignorují. Testovací matice jsou k dispozici v balíčku zadání. Při náhodném testu se některé z matic mohou změnit.
Výstupem programu je výpis testovacího protokolu. Příklady testovacích protokolů pro jednotlivé úrovně jsou dostupné v balíčku zadání. Některé testy vypisují celou matici, některé Pass
nebo Fail
, některé název výjimky, která byla vyvolána.
K výpisu celé matice je využitý vždy operátor «
, který máte naprogramovat. Příklad výstupu celé matice:
26 -57 99 -73 61 -8 -23 96 16 57 97 17 23 91 -95 -25
main.cpp
můžete dohledat, jak je každý z testů proveden. U testů s výstupem Pass
/Fail
, byste vždy měli dojít k hodnotě Pass
.
Při náhodném testu jsou spuštěny stejné testy, pouze je náhodně změněn obsah některých souborů matic. Mohou se změnit i rozměry matic.
Bonusovým zadáním je implementace funkcí úrovně označené L3.
BONUS: Úroveň L3 | ||
---|---|---|
Funkce/Operátor | Popis | Výjimky |
Matrix::Matrix(const std::vector<value> &v) | Konstruktor, který vytvoří čtvercovou matici. Prvky na hlavní diagonále jsou prvky vectoru v , ostatní prvky matice jsou nulové. Pracuje jako funkce diag() v Matlabu. | Žádné |
std::vector<value> operator () (void) const | Vrací vektor prvků na hlavní diagonále matice, ostatní prvky ignoruje. Pracuje jako funkce diag() v Matlabu. | Žádné |
void Matrix::changedim(int rows, int cols) | Změní rozměry matice. Dojde buď ke korektnímu oříznutí, nebo doplnění nulami. | matrix_negative_size při zadání záporné velikosti. |
Matrix horzcat (const Matrix & lhs, const Matrix & rhs) | Horizontální sloučení matic (ekvivalent [lhs, rhs] v Matlabu). | matrix_bad_sizes při nevhodných rozměrech. |
Matrix vertcat (const Matrix & top, const Matrix & bot) | Vertikálnísloučení matic (ekvivalent [top; bot] v Matlabu). | matrix_bad_sizes při nevhodných rozměrech. |
Matrix blkdiag (const Matrix & lhs, const Matrix & rhs) | Diagonální skládání matic. Vstupy musí byt čtvercové matice nebo skaláry (chovají se jako matice 1×1 ), zbytek je doplněn nulami. | matrix_bad_sizes při nevhodných rozměrech. |
Matrix blkdiag (const value & lhs, const Matrix & rhs) |
||
Matrix blkdiag (const Matrix & lhs, const value & rhs) |
||
Matrix blkdiag (const value & lhs, const value & rhs) |
||
Matrix kronecker (const Matrix & lhs, const Matrix & rhs) | Kroneckerův součin matic. | Žádné |
./main -l3
Odevzdává se balík s jakýmkoliv počtem souborů cpp nebo hpp s tím, že hlavní soubor main.cpp není třeba připojovat, bude nahrazen standardním souboraem, který je přiložen v šabloně HW04.zip .
Povinné i bonusové zadání | |
---|---|
Název v BRUTE | HW04 |
Argumenty při spuštění | -l1 , -l2 , -l3 |
Kompilace pomocí | g++ -pedantic -Wall -Werror -std=c++17 |
Procvičované oblasti | polymorfismus v C++, přetěžování operátorů, STL, hlavičkový soubor, algoritmizace |