Laboratorium nr 5: Mnożenie wektorów i macierzy

Podobne dokumenty
Zad. 3: Układ równań liniowych

Zad. 5: Układ równań liniowych liczb zespolonych

Laboratorium nr 4: Arytmetyka liczb zespolonych

Zad. 4: Rotacje 2D. 1 Cel ćwiczenia. 2 Program zajęć. 3 Opis zadania programowego

Zad. 3: Rotacje 2D. Demonstracja przykładu problemu skończonej reprezentacji binarnej liczb

Zad. 4: Szablonu dla układu równań liniowych

Zadanie nr 2: Arytmetyka liczb zespolonych

Zad. 6: Sterowanie robotem mobilnym

Zad. 5: Sterowanie robotem mobilnym

Układ równań liniowych

Zadanie nr 3: Sprawdzanie testu z arytmetyki

Zad. 5: Sterowanie dronem

Zadanie 2: Arytmetyka symboli

Zad. 5: Rotacje 3D. 1 Cel ćwiczenia. 2 Program zajęć. 3 Opis zadania programowego

Zad. 7: Fabryka obiektów i singleton

Zad. 4: Rotacje 3D. 1 Cel ćwiczenia. 2 Program zajęć. 3 Opis zadania programowego

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

Zad. 7: Sterowanie robotami mobilnymi w obecności przeszkód

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Pliki. Informacje ogólne. Obsługa plików w języku C

Podstawy programowania skrót z wykładów:

Operacje wejścia/wyjścia odsłona pierwsza

Mathcad c.d. - Macierze, wykresy 3D, rozwiązywanie równań, pochodne i całki, animacje

Metody numeryczne Laboratorium 2

Zad. 1: Sterowanie mimika

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Język C, tablice i funkcje (laboratorium)

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

IX. Wskaźniki.(3 godz.)

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Przeciążanie operatorów

Zad. 7: Sterowanie manipulatorem przypadek 3D

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 3. Karol Tarnowski A-1 p.

Podstawy Automatyki ćwiczenia Cz.1. Środowisko Matlab

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

1 Podstawy c++ w pigułce.

Dodatkowo klasa powinna mieć destruktor zwalniający pamięć.

1 Podstawy c++ w pigułce.

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Wprowadzenie do programu Mathcad 15 cz. 1

Algorytm. a programowanie -

po ostatnim dopisaniu na standardowe wyjście (cout) powinien zostać wyprowadzony komunikat "Skonczylem";

Zad. 6: Sterowanie dronami w obecności przeszkód

4. Wyrzuć wyjątek jeśli zmienna ist nie istnieje bloki: try, catch i wyrzucanie wyjątku

Podstawy Programowania

#include <stdio.h> int main( ) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }

Szablony funkcji i szablony klas

Część 4 życie programu

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Materiał. Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Funkcje Wskaźniki Referencje Tablice dynamiczne Typ string Przeładowania funkcji

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Nazwa wariantu modułu (opcjonalnie): Laboratorium programowania w języku C++

Język C, tablice i funkcje (laboratorium, EE1-DI)

Systemy operacyjne. Laboratorium 9. Perl wyrażenia regularne. Jarosław Rudy Politechnika Wrocławska 28 lutego 2017

Podstawy programowania. Wykład 6 Złożone typy danych: struktury, unie. Krzysztof Banaś Podstawy programowania 1

Języki i techniki programowania Ćwiczenia 2

Programowanie obiektowe

Diary przydatne polecenie. Korzystanie z funkcji wbudowanych i systemu pomocy on-line. Najczęstsze typy plików. diary nazwa_pliku

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

dr Mariusz Grządziel 15,29 kwietnia 2014 Przestrzeń R k R k = R R... R k razy Elementy R k wektory;

Ćwiczenie 1. Wprowadzenie do programu Octave

Rok akademicki: 2013/2014 Kod: JFT s Punkty ECTS: 5. Poziom studiów: Studia I stopnia Forma i tryb studiów: Stacjonarne

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

WYDZIAŁ ELEKTROTECHNIKI, AUTOMATYKI I INFORMATYKI INSTYTUT AUTOMATYKI I INFORMATYKI KIERUNEK AUTOMATYKA I ROBOTYKA STUDIA STACJONARNE I STOPNIA

2 Przygotował: mgr inż. Maciej Lasota

Podstawy programowania

Lab 9 Podstawy Programowania

Laboratorium 3: Preprocesor i funkcje ze zmienną liczbą argumentów. mgr inż. Arkadiusz Chrobot

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

public: // interfejs private: // implementacja // składowe klasy protected: // póki nie będziemy dziedziczyć, // to pole nas nie interesuje

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Wstęp do programowania. Wykład 1

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Układy równań i nierówności liniowych

Podstawy Programowania C++

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

C++ Przeładowanie operatorów i wzorce w klasach

Ćwiczenie 1. Wprowadzenie do programu Octave

Przetwarzanie sygnałów

Moduł Handlowo-Magazynowy Przeprowadzanie inwentaryzacji z użyciem kolektorów danych

Wartości domyślne, przeciażenia funkcji

Język C zajęcia nr 12. Struktury i unie

Programowanie współbieżne... (10) Andrzej Baran 2010/11

Wartości domyślne, przeciażenia funkcji

Baltie 3. Podręcznik do nauki programowania dla klas I III gimnazjum. Tadeusz Sołtys, Bohumír Soukup

Aproksymacja funkcji a regresja symboliczna

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Projekty zaliczeniowe Podstawy Programowania 2012/2013

Transkrypt:

Laboratorium nr 5: Mnożenie wektorów i macierzy 1 Cel ćwiczenia Wykształcenie umiejętności definiowania przeciążeń operatorów indeksujących i funkcyjnych. Utrwalenie umiejętności definiowania przeciążeń operatorów działających na wejściowych i wyjściowych strumieniach standardowych. 2 Program zajęć Ocena realizacji zadania z poprzedniego laboratorium ocenie podlega poprawność programu, kompilacja (kompilacja musi przebiegać bez ostrzeżeń), styl pisania programu oraz opisy, realizacja przeciążeń odpowiednich operatorów. Realizacja wstępnej fazy prac nad nowym zadaniem W ramach prac na zajęciach wymagane jest zdefiniowanie, jako niezbędne minimum struktury Wektor, której współrzędne będą liczbami zespolonymi. Zakładanym końcowym efektem tej fazy jest przeciążenie odpowiednich operatorów, które umożliwią wczytanie i wyświetlenie wektora ze współrzędnymi zespolonymi. Testowa wersja programu powinna być w stanie wczytać z wejścia standardowego kilka wektorów, aż do momentu jego wyczerpania (czytanie z pliku przekierowanego na wejście standardowe Uwaga: wewnatrz programu czytamy wyłacz- nie z wejścia standardowego). Ocena realizacji wstępnej wersji programu 3 Opis zadania programowego Należy napisać program, który umożliwi mnożenie macierzy o rozmiarze 4 4 i wektorów czterowymiarowych 1. Powinien on pozwalać na realizację trzech wariantów tej operacji, tzn. 1. mnożenie macierzy przez wektor, 2. mnożenie dwóch macierzy, 3. skalarny iloczyn dwóch wektorów. To jaki wariant ma być zrealizowany musi być rozpoznane na podstawie wczytywanych argumentów (chodzi o różnice w formacie zapisu macierzy i wektora). Program ma czytać argumenty z wejścia standardowego. Dla ułatwienia dostarczone są pliki testowe zawierające zestaw danych zapisanych w odpowiednich formatach. Czytanie ze wspomnianych plików ma być realizowane poprzez przekierowanie ich na wejście standardowe programu. Pliki dostarczone są w trzech wariantach, w których elementami poszczególnych macierzy i wektorów są: liczby wymierne, liczby zespolone oraz symbole (takie same jak w zadaniu nr 1). W kodzie programu typ elementów struktur danych modelujących wektor i macierz powinien być definiowany w oparciu o symbol dla preprocesora TYP, np. 1 Wektor w zapisie macierzowym traktujemy jako macierz jednokolumnowa. 1

#define TYP LiczbaZespolona struct Wektor { TYP x, y; }; Symbol TYP powinien być definiowany w osobnym pliku nagłówkowym, tak aby jego zmiana pozwalała skompilować cały program dla odpowiedniego wariantu danych. Plik ten może więc mieć postać #ifndef TYP_HH #define TYP_HH #define TYP LiczbaZespolona #endif Zakładając, że nazywa się on typ.hh plik nagłówkowy wektor.hh z definicją klasy Wektor może mieć następującą zawartość: #ifndef WEKTOR_HH #define WEKTOR_HH #include "liczbazespolona.hh" #include "symbol.hh" #include "typ.hh" struct Wektor { TYP x, y; }; #endif Analogiczne uwagi dotyczą konstrukcji klasy Macierz. Dla ułatwienia, zalążki tego typu konstrukcji udostępnione zostały w katalogu: bk/edu/kpo/zad/z5/zalazek 3.1 Działanie programu Program nie ma udostępniać żadnego interfejsu użytkownika. Zakłada się, że z wejściowego strumienia standardowego czytane są dwa argumenty. Każdy z nich może być macierzą lub wektorem. Dopuszczalne są trzy kombinacje tych argumentów, które warunkują rodzaj wykonywanej operacji. Te kombinacje to: pierwszy argument: macierz; drugi argument: wektor operacja: iloczyn macierzy i wektora, pierwszy argument: macierz; drugi argument: macierz operacja: iloczyn dwóch macierzy, pierwszy argument: wektor; drugi wektor: wektor operacja: iloczyn skalarny dwóch wektorów. 2

Czwartą kombinację, tzn. gdy pierwszy argument jest wektorem, a drugi macierzą traktujemy w tym programie jako zabronioną 2. Program ma rozpoznawać taką sytuację i informować, że nie jest przystosowany do realizacji tego typu operacji. Program po wczytaniu dwóch argumentów ma je wyświetlić, a następnie wykonać zadane działanie i wyświetlić jego wynik. Następnie operacja ta jest powtarzana, aż do momentu wyczerpania danych na wejściu standardowym (napotkanie końca pliku, operujemy na wejściu standardowy, ale to wejście też może zostać wyczerpane, np. przekierowujemy na nie plik). Program powinien dokonywać rozróżnienia między wektorem, a macierzą po pierwszym wczytanym znaku. Znak ten można później zwrócić do strumienia i wczytać całość odpowiednio jako wektor lub macierz. Poniżej przedstawiony jest przykład działania programu. jkowalsk@noxon: rozwiazanie>./mnozenie < liczby_zespolone.dane ---- Operacja dwuargumentowa -------- Argument nr 1: (0+1i) (1+0i) (0+0i) (0+0i) (1+1i) (2+0i) (1+1i) (0+0i) (0+0i) (0+0i) (0+0i) (0+0i) (0+0i) (0+0i) (0+0i) (0+0i) Argument nr 2: ( (1+0i), (0+0i), (0+0i), (0+0i) ) Wynik: ( (0+1i), (1+1i), (0+0i), (0+0i) ) ---- Operacja dwuargumentowa -------- Argument nr 1: ( (1+0i), (0+2i), (0+0i), (0+0i) ) Argument nr 2: ( (1+0i), (0+1i), (0+0i), (1+5i) ) Wynik: (-1+0i) ---- Operacja dwuargumentowa -------- Blad danych! Wykryto niedozowlony rodzaj pierwszego argumentu. Dzialanie programu zostalo przerwane. 2 Operacja mnożenia wektora przez macierz jest operacją dopuszczalną i poprawną pod warunkiem, że wektor będzie wektorem transponowanym. 3

jkowalsk@noxon: rozwiazanie>_ 3.2 Format plików z danymi Pliki z danymi mogą zawierać macierze lub wektory. Wykonując działania mnożenia macierzy przez wektor, te ostatnie traktujemy jako macierze jednokolumnowe. Jednak, aby w zapisie móc je odróżnić od macierzy, przyjęto zwyczajową formę zapisu ograniczoną nawiasami półokrągłymi, w której kolejne współrzędne rozdzielone są przecinkami. Przykładowy zapis macierzy dla liczb zespolonych jest przedstawiony w opisie działania programu. Poniżej przedstawiony jest przykładowy zapis macierzy w przypadku liczb wymiernych. 1.24 3.22 0.00 4.55 1.00 1.21 1.00 0.05 0.00 0.01 0.21 2.30 0.24 0.20 0.10 4.10 Zapis dla symboli: a c d e e e d a e b a a d e d a Zapis wektora dla liczb zespolonych dostępny jest w opisie działania programu. Poniżej przedstawiony jest zapis wektora dla liczb wymiernych. ( 2.33, 4.55, 6.11, 0.01 ) Dla symboli ma on postać: ( a, b, e, a ) 3.3 Wymagania co do konstrukcji programu Oprócz wymagań sformułowanych w opisie zadania należy uwzględnić uwarunkowania przedstawione poniżej. Należy zdefiniować strukturę Wektor oraz Macierz. Muszą one mieć tylko i wyłącznie niezbędne pola. Należy odpowiednio przeciążyć operator indeksujący dla klasy Wektor, operator funkcyjny dla klasy Macierz i odpowiednio posługiwać się nimi w programie. Należy przeciążyć operatora mnożenia, tak aby była możliwość przemnożenia macierzy przez wektor, macierzy przez macierz, oraz wektora przez wektor. Program musi zachować strukturę modułową i odpowiednią strukturę kartotek. O ile będzie to konieczne, należy zmodyfikować plik Makefile (np. gdy dodany zostanie nowy moduł). Program musi mieć oddzielne moduły dla działań na liczbach zespolonych i symbolach. 4

Wszystkie metody, przeciążenia operatorów, które nie zmieniają stanu obiektu, na którym działają, powinny być metodami typu const. Oprócz tego pozostają w mocy wszystkie wcześniejsze wymagania dotyczące struktury katalogów, pliku Makefile, modułowej struktury programu, jak też opisów. 3.4 Pomoc W katalogu bk/edu/kpo/zad/z5/zalazek został dostarczony zalążek konstrukcji programu. Zawiera on testowy zestaw danych dla każdego przypadku (tzn. typu double, LiczbaZespolona i Symbol). Pozwala on również na usprawnienie pracy. Aby przełączyć się, np. z typu double na typ LiczbaZespolona wystarczy napisać polecenie: make LiczbaZespolona Spowoduje ono następujące akcje: 1. zmieni zawartość pliku inc/type.hh na #ifndef TYP_HH #define TYP_HH #define TYP LiczbaZespolona #endif 2. przekopiuje plik./dane/test-liczbazespolona.dane do kartoteki, w której jest plik Makefile, binarny plik programu, nada kopiowanemu plikowi nazwę./test.dane, 3. usunie wcześniejsze produkty kompilacji i konsolidacji, 4. wymusi kompilację dla nowej wersji, a następnie jej konsolidację pod nazwą./mnozenie, 5. jeśli wszystko zakończyło się powodzeniem, to uruchomi program w następujący sposób: mnozenie < test.dane Od momentu wykonania opisanej wyżej formy polecenia make, dalsze kompilacje i konsolidacje oraz wywołania programu po wykonaniu samego polecenia make będą realizowane dla typu LiczbaZespolona. Przełączenie procesu kompilacji i konsolidacji na dwa pozostałe typy, tzn. double i Symbol, jest realizowane analogicznie. 3.5 Wersja bardzo uproszczona oceniana nie więcej niż na 3,5 W tej wersji wystarczy ograniczyć się do macierzy 2 2 i wektorów dwuwymiarowych. Program po uruchomieniu czyta wyłącznie dwa pierwsze argumenty z pliku i wykonuje odpowiednie działanie. 5

3.6 Wersja rozszerzona nieobowiazkowa 3.6.1 Rozszerzenie małociekawe Zakładamy, że rozmiar macierzy i wektorów nie jest z góry znany (jednak jest mniejszy niż 20 korzystamy z tablic, a nie ze struktur dynamicznych). Zakładamy, że informacja o rozmiarze znajduje się w pliku z danymi i jest to pierwszy element tego pliku, np. 5 1.24 3.22 0.00 4.55 3.22 1.00 1.21 1.00 0.05 7.12 0.00 0.01 0.21 2.30 4.52 0.24 0.20 0.10 4.10 1.21 0.00 0.01 3.21 2.30 9.53 ( 2.33, 4.55, 6.11, 0.01, 4.55 ) 3.6.2 Rozszerzenie ciekawsze Zakładamy, że rozmiar wczytywanych macierzy i wektorów nie jest określony. W pliku danych nie ma żadnej dodatkowej informacji. Rozmiar ustalany jest on w trakcie czytania macierzy lub wektora. Uwaga: W tym przypadku trzeba sprawdzić przed wykonaniem operacji mnożenia, że rozmiary są zgodne. W przypadku, gdy tak nie jest należy zaniechać realizacji tej operacji i wyświetlić odpowiednią informację. A Dodatek Niniejszy dodatek zawiera informacje, które mogą być użyteczne przy pisaniu programu realizowanego w ramach tego zadania. A.1 Podstawy matematyczne Załóżmy, że mamy dwa wektory u=(u 1,u 2,...,u n ), v=(v 1,v 2,...,v n ) o współrzędnych zespolonych. Ich iloczyn skalarny definiujemy jako: gdzie v i to liczba sprzężona do v i. u v= n i=1 u i v i A.2 Problem ujednolicenia względem typów W niniejszym zadaniu występują dwa zasadnicze problemy, które utrudniają proste napisanie programu, tak aby można było bez kłopotów skompilować go dla typów double, LiczbaZespolona lub Symbol. Pierwszym z nich jest zerowanie macierzy lub wektora. Drugim jest zapis iloczynu skalarnego dwóch wektorów. 6

A.2.1 Zerowanie zmiennej Zerowanie macierzy lub wektora sprowadza się do bardziej elementarnego problemu, jakim jest zerowanie pojedynczej zmiennej. Rozważmy przykład zmiennej Zm dla trzech kolejnych typów. W przypadku typu double operację zerowania możemy zapisać jako double Zm; Zm = 0; Dla typu LiczbaZespolona będzie to double Zm; Zm.re = 0; Zm.im = 0; Natomiast dla typu Symbol zapis ten sprowadzi się do postaci Symbol Zm; Zm = e; Aby ujednolicić tę operację, wystarczy że zdefiniujemy dla każdego z typów funkcję Zeruj. Wówczas zapis wcześniejszych operacji sprawdzi się do postaci TYP Zm; Zeruj(Zm); Podejście takie jest możliwe dzięki mechanizmowi przeciążeń. Funkcja Zeruj powinna zostać zdefiniowana odpowiednio w module liczbyzespolone.cpp oraz symbol.cpp (w odpowiednich plikach nagłówkowych powinna być zapowiedź definicji tej funkcji). Wskazane jest stworzenie analogicznego modułu dla typu double. A.2.2 Zapis iloczynu skalarnego W przypadku iloczynu skalarnego pojawia się problem utworzenie wartości zespolonej dla przypadku struktury LiczbaZespolona. Jednak ponownie możemy to ujednolicić analogicznie jak w przypadku zerowania. Zamiast posługiwać się metodą struktury LiczbaZespolona zwracającą wartość sprzężoną, możemy zdefiniować funkcję WartoscSprzezona dla wszystkich trzech typów. W przypadku typów double i Symbol funkcja ta będzie zwracała tę samą wartość, która jest jej argumentem. A.3 Wczytywanie danych W tym zadaniu, aby wczytać pierwszy argument należy podejrzeć od jakiego znaku on się zaczyna. Wydaje się, że najlepszym rozwiązaniem jest zastosowanie metody peek. Jednak jest to jedno z najgorszych rozwiazań (gorszym jest jedynie wcześniejsze wczytanie całej linii do tablicy i dalsza jej analiza). Ze względu na znaki białe właściwym rozwiązaniem jest wczytanie znaku, jego rozpoznanie i późniejsze jego zwrócenie do strumienia, a więc cin >> Znak;... cin.unget(); Najlepszym rozwiązaniem jest taka organizacja przeciążenia operatora czytania odpowiednio dla wektora i macierzy, aby po wykryciu niezgodności pierwszego znaku był on zwracany do strumienia, a strumień ustawiony w stan fail. 7