====== Struktura kodu ======
Kod będziemy umieszczali w folderach o strukturze pozwalającej na zapis wszystkich projektów w repozytorium kodu ustalonym indywidualnie dla każdego uczestnika.
*Utwórz katalog //root// Może to być np. ''programowanie-obiektowe'' lub Twoje imię i nazwisko
*Skopiuj tam do osobnego katalogu ''Lab1'' pliki utworzone podczas pierwszych zajęć
*Kod utworzony podczas kolejnych laboratoriów ma być umieszczany w katalogach ''Lab2'', ''Lab3'', itd.
*Czyli pliki utworzone podczas tych zajęć mają trafić do ''Lab2''
====== Laboratorium 2 ======
Klasa Matrix jest macierzą dwuwymiarową, ale dane przechowuje w tablicy jednowymiarowej ''data''. Informacja o liczbie wierszy i kolumn jest zawarta w polach ''rows'' i ''cols''
public class Matrix {
double[]data;
int rows;
int cols;
//...
Matrix(int rows, int cols){
this.rows = rows;
this.cols = cols;
data = new double[rows*cols];
}
//...
}
Celem ćwiczenia jest implementacja różnych metod klasy Matrix oraz ich **przetestowanie**. Możesz wpierw wykonać punkt [[#dodaj_kod_testujacy|2.11]] i dodawać kod testujący na bieżąco...
===== 2.1 Zaimplementuj konstruktor =====
Matrix(double[][] d){
tworzący macierz na podstawie tablicy - liczba kolumn ma być ustalona na podstawie najdłuższego wiersza w d, brakujace elementy zerowe.
Matrix m = new Matrix(new double[][]{{1,2,3,4},{5,6},{7,8},{9}});
{{ :po:20181018_141630.jpg?600 |}}
===== 2.2 Zaimplementuj metodę która zwraca tablicę dwuwymiarową =====
double[][] asArray()
===== 2.3 Zaimplementuj metody dostępu do elementów (settery i gettery) =====
double get(int r,int c)
void set (int r,int c, double value)
===== 2.4 Zaimplementuj metodę toString =====
Publiczna funkcja ''toString'' powinna zwracać tekstową reprezentację obiektu. Klasa ''String'' jest niemodyfikowalna (//immutable//), dlatego do przygotowania tekstu użyj klasy ''StringBuilder''. Obiekty tej klasy są modyfikowalne i bufor dla tekstu może automatycznie przyrastać w miarę dodawania kolejnych fragmentów. Przeciążona metoda ''append()'' pozwala na dopisywania tekstowej reprezentacji obiektów różnych typów (''String'', ''Object'', ''double'', ''float'', ''int'', itd.)
public String toString(){
StringBuilder buf = new StringBuilder();
buf.append("[")
for(int i=0;i
===== 2.5 Zaimplementuj metodę reshape =====
void reshape(int newRows,int newCols){
if(rows*cols != newRows*newCols)
throw new RuntimeException(String.format("%d x %d matrix can't be reshaped to %d x %d",rows,cols,newRows,newCols));
}
Na razie informuj o błędach za pomocą wyjątku RuntimeException. **Jest to bardzo niewłaściwe i żaden programista Javy nigdy nie powinien tego robić**. ;-) Ale niektórzy tak robią i zostaje w bibliotekach na długie lata.
===== 2.6 Zaimplementuj metodę shape =====
Metoda powinna zwracać tablicę określającą liczbę wierszy i kolumn
int[] shape()
===== 2.7 Zaimplementuj metodę add =====
Matrix add(Matrix m)
Zwraca ona macierz, której elementy spełniają
assert( get(i,j) == this.get(i,j)+m.get(i,j) )
===== 2.8 Analogicznie zaimplementuj metody =====
Matrix sub(Matrix m){...}
Matrix mul(Matrix m){...}
Matrix div(Matrix m){...}
oraz dodawanie, mnożenie, dzielenie, odejmowanie skalarów
Matrix add(double w){...} // dodaje wartość w do każdego elementu
Matrix sub(double w){...} // odejmuje wartośc w od kazdego elementu
Matrix mul(double w){...} // mnoży każdy element przez skalar w
Matrix div(double w){...} // dzieli każdy element przez skalar w
===== 2.9 Zaimplementuj zwykłe mnożenie macierzy. =====
W wyniku pomnożenia A(r x n) * B(n x m) ma powstać macierz C(r x m)
Matrix dot(Matrix m)
===== 2.10 Zaimplementuj normę Frobeniusa =====
Norma Frobeniusa to po prostu suma kwadratów elementów.
[[https://en.wikipedia.org/wiki/Matrix_norm#Frobenius_norm]]
double frobenius()
Czyli jeżeli odejmiemy macierz od siebie - to powinna powtać macierz o zerowej normie Frobeniusa. Jeśli podzielimy przez siebie - norma powinna wynosić ''rows * cols''
===== 2.11 Dodaj kod testujący =====
** Uwaga :!: To zadanie przeniesione na następne laboratorium **
Dla każdej z wcześniej podanych metod napisz kod testowy.
*Dodaj klasę ''TestMatrix'' (w tym samym pakiecie)
*Zaimplementuj kolejno statyczne metody o nazwie ''testXXX'', np:
* ''testMatrix()'' - test konstruktora
* ''testAdd()'' - test dodawania
* itd.
*Następnie wywołaj je w funkcji ''main''
===== 2.12 Opcjonalnie: metody statyczne budujące macierze =====
Często spotykaną konwencją jest stosowanie metod statycznych, które tworzą skonfigurowany obiekt
Zaimplementuj typowe metody:
public static Matrix random(int rows, int cols){
Matrix m = new Matrix(rows,cols);
Random r = new Random();
m.set(0,0,r.nextDouble());
//... wypełnij wartościami losowymi
return m;
}
Wywołanie:
Matrix r = Matrix.random(2,3);
Macierz jednostkowa
public static Matrix eye(int n){
Matrix m = new Matrix(n,n);
//... wypełnij jedynkami na przekątnej
return m;
}
===== 2.13 Opcjonalnie: odwracanie macierzy =====
Jeżeli ktoś ma ochotę może napisać metodę ''inv()'' zwracającą odwrotność macierzy. Macierz może być odwrócona metodą [[https://en.wikipedia.org/wiki/Gaussian_elimination|eliminacji Gaussa]].
Znalazłem gdzieś na dysku stary kod w C++ z 1995 roku. Może się przydać jako źródło inspiracji... Wydaje mi się, że działał?
*Konstruktor tworzył macierz jednostkową (z jedynkami na przekątnej)
*Pivot to element maksymalny w obszarze do eliminacji
*Nie chcemy wersji //in place//. Po prostu wynikowa macierz ma być zwracana
*Testy - pomnóż wektor przez macierz i następnie jej odwrotność i sprawdź, czy osiągnięto wartość wyjściową. Albo pomnóż macierz przez odwrotność i sprawdź, czy wynikowa macierz jest jednostkowa.
void Matrix::swapRows(int i1,int i2)
{
for(int j=0;jverySmall ){
for(j=0;j