Spis treści

Macierze komórkowe i struktury

Komórka - obiekt typu cell

# komórka (cell) zawierająca liczbę calkowitą 42
a = { 42 }

# komórka (cell) zawierająca znak 'A'
b = { 'A' }

# komórka z napisem 
c = { 'Siała baba mak' }

whos a b c
a =
{
  [1,1] =  42
}

b =
{
  [1,1] = A
}

c =
{
  [1,1] = Siała baba mak
}

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x1                          8  cell
        b           1x1                          1  cell
        c           1x1                         15  cell

Total is 3 elements using 24 bytes

Wektory i macierze komórkowe

# wektor komórkowey wierszowy
c = { 42, 'A', 1:3:10, 'Witaj'} 
whos c
c =
{
  [1,1] =  42
  [1,2] = A
  [1,3] =

      1    4    7   10

  [1,4] = Witaj
}

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        c           1x4                         38  cell

Total is 4 elements using 38 bytes
# wektor kolumnowy
c = { 42; 'A'; 1:3:10; 'Witaj'} 
size(c)
c =
{
  [1,1] =  42
  [2,1] = A
  [3,1] =

      1    4    7   10

  [4,1] = Witaj
}

ans =

   4   1
# macierz komórkowa 2x2
c = { 42, 'A'; 1:3:10, 'Witaj'} 
size(c)
c =
{
  [1,1] =  42
  [2,1] =

      1    4    7   10

  [1,2] = A
  [2,2] = Witaj
}

ans =

   2   2
# elementami macierzy komórkowej moga być macierze komórkowe
d = { c , c ; 1, 'A'}
whos d
d =
{
  [1,1] =
  {
    [1,1] =  42
    [2,1] =

        1    4    7   10

    [1,2] = A
    [2,2] = Witaj
  }

  [2,1] =  1
  [1,2] =
  {
    [1,1] =  42
    [2,1] =

        1    4    7   10

    [1,2] = A
    [2,2] = Witaj
  }

  [2,2] = A
}

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        d           2x2                         85  cell

Total is 4 elements using 85 bytes

Alokacja pustej macierzy komórkowej

## pusta macierz - prealikacja macierzy komórkowej
x = cell(2, 3)
whos x
x =
{
  [1,1] = [](0x0)
  [2,1] = [](0x0)
  [1,2] = [](0x0)
  [2,2] = [](0x0)
  [1,3] = [](0x0)
  [2,3] = [](0x0)
}

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        x           2x3                          0  cell

Total is 6 elements using 0 bytes
# ewentualnie można utworzyć macierz inicjując jej najdalszy element
y{2,3} = []
y =
{
  [1,1] = [](0x0)
  [2,1] = [](0x0)
  [1,2] = [](0x0)
  [2,2] = [](0x0)
  [1,3] = [](0x0)
  [2,3] = [](0x0)
}

Ćwiczenie: utwórz macierz komórkową o wymiarach 2×3 zawierającą 6 nastepujących elementów: * dzisiejsza data (zob. polecenie data) * tablica 2-elementowa zawierająca aktualną godzinę i minutę (zob. polecenie clock) * macierz jednostkowa o wymiarach 10×10 * napis “Witaj Świcie” * wektor wierszowy zawierający liczby calkowite od 1 do 100 * wektor 6 losowych liczb całkowitych z puli od 1 do 49 (wyniki losowanoa lotto) w kolejnosci rosnącej (zob. funkcję randi)

Indeksowanie elementów obiektu typu cell

x = { 42, 'A'; 1:3:10, 'Witaj'};

% indeksowanie wartości (1,1)
a = x{1,1}

% indeksowanie komórek
b = x(1,1)
whos a b
a =  42
b =
{
  [1,1] =  42
}

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x1                          8  double
        b           1x1                          8  cell

Total is 2 elements using 16 bytes
x = { 42, 'A'; 1:3:10, 'Witaj'};

% elementem {2,1} jest wektor 
a = x{2,1}

% element 1 wektora z komórki x{2,1}
c = x{2, 1}(1)   
a =

    1    4    7   10

c =  1
% elementem (2,1) jest komórka zawierająca wektor
b = x(2, 1)

% element 1 wektora znajdującago się w pierwszej komórce znajdującej się w x(2,1) 
d = x(2, 1){1}(1)
whos a b c d
b =
{
  [1,1] =

      1    4    7   10

}

d =  1
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x4                         24  double
        b           1x1                         24  cell
        c           1x1                          8  double
        d           1x1                          8  double

Total is 7 elements using 64 bytes

Ineksowanie za pomoca dwukropka :

x = { 42, 'A', 1:3:10, 'Matlab'};

# pierwsze 3 elementy - 3 różne zmienne ans
x{1:3}
ans =  42
ans = A
ans =

    1    4    7   10
% wynik można podstawić do 3 róznych zmiennych
[a b c] = x{1:3}

whos a b c
a =  42
b = A
c =

    1    4    7   10

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x1                          8  double
        b           1x1                          1  char
        c           1x4                         24  double

Total is 6 elements using 33 bytes
% wynikiem x(1:3) nowa macierz komórkowa
x(1:3)

% wynikiem jest jedna zmienna
a = x(1:3)
whos a x
ans =
{
  [1,1] =  42
  [1,2] = A
  [1,3] =

      1    4    7   10

}

a =
{
  [1,1] =  42
  [1,2] = A
  [1,3] =

      1    4    7   10

}

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x3                         33  cell
        x           1x4                         39  cell

Total is 7 elements using 72 bytes
% indeksowanie podobne jak w macierzach
x = { 42, 'A'; 1:3:10, 'Matlab'};

% pierwsza kolumna
a = x(1, :)

% ostatni wiersz
b = x(end, :)
a =
{
  [1,1] =  42
  [1,2] = A
}

b =
{
  [1,1] =

      1    4    7   10

  [1,2] = Matlab
}

Wyświetlanie zawartości komórek

x = { 42, 'A'; 1:3:10, 'Matlab'};

disp(x)
celldisp(x)
{
  [1,1] =  42
  [2,1] =

      1    4    7   10

  [1,2] = A
  [2,2] = Matlab
}
x{1,1} = 

 42

x{2,1} = 

    1    4    7   10

x{1,2} = 

A

x{2,2} = 

Matlab
% wyświetlanie rekurencyjne macierzy komórkowych zawierających inne macierze komórkowe
y = {1, 2, x}
celldisp(y)
y =
{
  [1,1] =  1
  [1,2] =  2
  [1,3] =
  {
    [1,1] =  42
    [2,1] =

        1    4    7   10

    [1,2] = A
    [2,2] = Matlab
  }

}

y{1} = 

 1

y{2} = 

 2

y{3}{1,1} = 

 42

y{3}{2,1} = 

    1    4    7   10

y{3}{1,2} = 

A

y{3}{2,2} = 

Matlab
% celplot() nie jest dostępne w Octave
cellplot(x)
warning: the 'cellplot' function is not yet implemented in Octave

Please read <https://www.octave.org/missing.html> to learn how you can
contribute missing functionality.
error: 'cellplot' undefined near line 2 column 1

Funkcje macierzowe

x = { 42, 'A'; 1:3:10, 'Matlab'};

% rozmiar
[w k] = size(x)

% transpozycja
y = x'
w =  2
k =  2
y =
{
  [1,1] =  42
  [2,1] = A
  [1,2] =

      1    4    7   10

  [2,2] = Matlab
}
% zmiana kształtu
reshape(x, [1, 4])

% usuwanie elementów
x(1, :) = []
ans =
{
  [1,1] =  42
  [1,2] =

      1    4    7   10

  [1,3] = A
  [1,4] = Matlab
}

x =
{
  [1,1] =

      1    4    7   10

  [1,2] = Matlab
}

Macierz komórkowa z napisami

tekst = {'Ala ma kota', 'Siała baba mak', 'Matlab'} 
tekst =
{
  [1,1] = Ala ma kota
  [1,2] = Siała baba mak
  [1,3] = Matlab
}

Przydatne funkcje

x = char('Ala', 'Ewa', 'Zenon')

% utowrzenie macierzy komorkowej znakowej (3 napisy)
y = cellstr(x)
whos x y
x =

Ala  
Ewa  
Zenon

y =
{
  [1,1] = Ala
  [2,1] = Ewa
  [3,1] = Zenon
}

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        x           3x5                         15  char
        y           3x1                         11  cell

Total is 18 elements using 26 bytes
disp(y{1})     % napis 'Ala'
a = length(y{1})      

disp(x(1, :))     % napis 'Ala  '  (2 spacje na koncu)
b = length(x(1, :)) 
Ala
a =  3
Ala  
b =  5
tekst = {'Ala', 'Ewa', 'Zenon'};

% utworzenie macierzy znakowaej 3x5
x = char(tekst)
whos x
x =

Ala  
Ewa  
Zenon

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        x           3x5                         15  char

Total is 15 elements using 15 bytes
tekst = {'raz', 'dwa', 'trzy', 'cztery'};
s = char(tekst);

whos tekst s

% czy macierz komórkowa znakowa ?
a = iscellstr(tekst)      
b = iscellstr(s)
c = iscellstr({1 , 'A', 'Ala'})
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        tekst       1x4                         16  cell
        s           4x6                         24  char

Total is 28 elements using 40 bytes

a = 1
b = 0
c = 0

Ćwiczenie: utwórz tablicę komórkową zawierająca listę imion (np. Ala, Ewa, Janek), drugą zawierająca listę czasowników (np. lubi, je, czyta) i trzecia zawierającą rzeczowniki (np. kamienie, kotlety, koty). Napisz wyrażenie (lub funkcję), które tworzy zdania losując po jednym wyrazie z każdego zbioru (np. Ala lubi koty)

Struktury

struct(nazwa1, wartosc1, nazwa2, wartość2, ...)

# utowrzenie struktury za pomoca przypisania wartości
s1.liczba = 42
s1.nazwa = 'Matlab'
s1.macierz = rand([2,3])
s1 =

  scalar structure containing the fields:

    liczba =  42

s1 =

  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab

s1 =

  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab
    macierz =

       0.90546   0.84410   0.50294
       0.29388   0.36011   0.69174
# utowrzenie struktury za pomoca funkcji struct()
s2 = struct('liczba', 42, 'nazwa', 'Matlab', 'macierz', rand([2,3]))

whos s1 s2   % ta struktura jest macierza 1x1
s2 =

  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab
    macierz =

       0.241836   0.230792   0.186499
       0.099092   0.119201   0.122511


Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        s1          1x1                         62  struct
        s2          1x1                         62  struct

Total is 2 elements using 124 bytes

Przydatne funkcje

s = struct('liczba', 42, 'nazwa', 'Matlab', 'macierz', rand(5));
disp(s)

% nazwy pól struktury 
nazwy = fieldnames(s)
  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab
    macierz =

       0.038913   0.317290   0.831178   0.354825   0.522132
       0.736033   0.781280   0.281603   0.907320   0.272378
       0.244622   0.653326   0.608465   0.268054   0.593301
       0.818070   0.741613   0.449265   0.981028   0.870832
       0.224464   0.475633   0.370601   0.401830   0.257715

nazwy =
{
  [1,1] = liczba
  [2,1] = nazwa
  [3,1] = macierz
}
% nie modyfikuje struktury ale zwraca kopię
rmfield(s, 'macierz') 

% aktualna zawartość struktury
disp(s)
ans =

  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab

  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab
    macierz =

       0.038913   0.317290   0.831178   0.354825   0.522132
       0.736033   0.781280   0.281603   0.907320   0.272378
       0.244622   0.653326   0.608465   0.268054   0.593301
       0.818070   0.741613   0.449265   0.981028   0.870832
       0.224464   0.475633   0.370601   0.401830   0.257715
% podstawiamy wynik aby zachować zmiany
s = rmfield(s, 'macierz')
disp(s)
s =

  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab

  scalar structure containing the fields:

    liczba =  42
    nazwa = Matlab
% czy struktura zawiera pole o danej nazwie?
a = isfield(s, 'liczba')
b = isfield(s, 'xxx')
a = 1
b = 0

Do pól struktury możemy odnosić się również używając nazw pól w postaci łańcuchów znakowych

s = struct('liczba', 42, 'nazwa', 'Matlab', 'macierz', rand(5));

% pole o nazwie 'liczba'
a = s.('liczba')

t = 'nazwa'
% nazwa pola zawarta w zmiennej
b = s.(t)

n = fieldnames(s);

for i=1:length(n)
    fprintf('\nPole o nazwie %s\n', n{i})
    disp(s.(n{i}))
end
a =  42
t = nazwa
b = Matlab

Pole o nazwie liczba
 42

Pole o nazwie nazwa
Matlab

Pole o nazwie macierz
   0.912414   0.920362   0.263780   0.128573   0.340286
   0.663009   0.914018   0.881667   0.286782   0.813027
   0.648888   0.489993   0.766774   0.403041   0.284646
   0.651711   0.414582   0.074597   0.489842   0.120202
   0.136358   0.300551   0.394563   0.728933   0.287581

Wektory i macierze struktur

sm(1).pole = 5
sm(2).pole = 42

whos sm
sm =

  scalar structure containing the fields:

    pole =  5

sm =

  1x2 struct array containing the fields:

    pole

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        sm          1x2                         16  struct

Total is 2 elements using 16 bytes
# prealokacja macierzy strukrur przez zdefiniowanie ostatniego elementu

sa(10).pole = 3
whos sa
disp(sa)
sa =

  1x10 struct array containing the fields:

    pole

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        sa          1x10                         8  struct

Total is 10 elements using 8 bytes

  1x10 struct array containing the fields:

    pole
% macierz 10x10 pustych elementów (tylko sb(10,10) jest strukturą z wartością pola 5 ) 
sb(10,10).pole = 5

whos sb

disp(sb)

sb(1,1)
sb(10,10)
sb =

  10x10 struct array containing the fields:

    pole

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        sb         10x10                         8  struct

Total is 100 elements using 8 bytes

  10x10 struct array containing the fields:

    pole
ans =

  scalar structure containing the fields:

    pole = [](0x0)

ans =

  scalar structure containing the fields:

    pole =  5
% alokacja macierzy struktur za pomocą funkcji repmat
s3 = repmat(struct('pole', 42, 'nazwa', 'Matlab'), 2, 3)

whos s3
disp(s3)

a = s3(1, 2).pole
s3.pole
whos a
s3 =

  2x3 struct array containing the fields:

    pole
    nazwa

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        s3          2x3                         84  struct

Total is 6 elements using 84 bytes

  2x3 struct array containing the fields:

    pole
    nazwa
a =  42
ans =  42
ans =  42
ans =  42
ans =  42
ans =  42
ans =  42
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x1                          8  double

Total is 1 element using 8 bytes

Elementy pól wybranych struktur mogą być uzyte do utworzenia macierzy z tymi elementami

% umieszczenie wartości pól struktury w wektorze
a = [ s3.pole ]
whos a
size(a)
a =

   42   42   42   42   42   42

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x6                         48  double

Total is 6 elements using 48 bytes

ans =

   1   6

Zagnieżdzone struktury

st = struct('pole1', struct('a', 13, 'b', 14), 'pole2', struct('x', -1))
disp(st)

% pole 1 jest strukturą
a = st.pole1

% struktura w polu1 ma pole 'a'
b = st.pole1.a
st =

  scalar structure containing the fields:

    pole1 =

      scalar structure containing the fields:

        a =  13
        b =  14

    pole2 =

      scalar structure containing the fields:

        x = -1


  scalar structure containing the fields:

    pole1 =

      scalar structure containing the fields:

        a =  13
        b =  14

    pole2 =

      scalar structure containing the fields:

        x = -1

a =

  scalar structure containing the fields:

    a =  13
    b =  14

b =  13

Ćwiczenie zaprojektuj i utwórz strukturę, która będzie przechowywała dane dotyczące studenta, takie jak: imię, nazwisko, data urodzenia (data jest też strukturą zawierającą pola: dzień, miesiąc, rok), miejsce zamieszkania (adres zawiera pola: ulica, numer domu, kod pocztowy, kraj). Wprowadź przykładowe dane do struktury.

Utwórz macierz 100×100 zawierającą kopie tej struktury w każdym elemencie.

Zamiana struktury na macierz komórkową

c = {'A', 1, 'Ala', [12,3]};

% utworzenie struktury z nazwami pól 'a', 'b', 'c', 'd'
d = cell2struct(c, {'a', 'b', 'c', 'd'}, 2)
disp(d)
whos c d
d =

  scalar structure containing the fields:

    a = A
    b =  1
    c = Ala
    d =

       12    3


  scalar structure containing the fields:

    a = A
    b =  1
    c = Ala
    d =

       12    3

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        c           1x4                         28  cell
        d           1x1                         28  struct

Total is 5 elements using 56 bytes
% utworzenie macierzy komórkowej ze struktury
e = struct2cell(d)
disp(e)
whos e
e =
{
  [1,1] = A
  [2,1] =  1
  [3,1] = Ala
  [4,1] =

     12    3

}

{
  [1,1] = A
  [2,1] =  1
  [3,1] = Ala
  [4,1] =

     12    3

}
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        e           4x1                         28  cell

Total is 4 elements using 28 bytes

Zadanie 8. Licz znaki

Stwórz plik o nazwie licz_znaki.m a w nim zdefiniuj funkcję o nazwe licz_znaki(), która dla podanego w argumencie napisu zwraca strukturę zawierającą nastepujące pola:

Argumentem funkcji może być napis lub tablica komórkowa z napisami. Jeżeli argumentem jest pojedynczy napis to wynikiem jest pojedyncza struktura. Jeżeli argumentem jest tablica komórkowa znakowa to wynikiem jest macierz struktur o takim samym wymiarze jak tablica komórkowa dana w argumencie. Każdy element macierzy wynikowej zlicza wówczas znaki odpowiadającego elementowi macierzy komórkowej (zobacz przykład niżej) W przypadku, gdy funkcja zostanie uruchomiona z argumentami innego typu lub w przypadku gdy uzytkonik poda niepoprawną ilość argumentów (różną od 1) to wypisywany jest stosowny komunikat błedu i program się kończy.

Przykład

Uruchomienie funkcji

x = licz_znaki('Ala ma kota')

zwróci strukturę zawierającą wartości:

x.znaki = 11
x.litery = 9
x.wyrazy = 3

Gdy argumentem będzie macierz komórkowa z napisami to wynikiem bedzie macierz struktur, np.:

a = { 'Ala ma kota', 'Matlab'};
x = licz_znaki(a)

utowrzy zmienną x, która jest macierzą 1×2

x(1,1).znaki = 11
x(1,1).litery = 9
x(1,1).wyrazy = 3

x(1,2).znaki = 6
x(1,2).litery = 6
x(1,2).wyrazy = 1