From fa32f4a3fdebd698b0ef5f176742aed1386e6802 Mon Sep 17 00:00:00 2001 From: Enrico Lumetti Date: Mon, 15 Mar 2021 17:41:55 +0100 Subject: [PATCH] First commit --- BasicClass.m | 25 +++++++++++++++ basic_casting.m | 9 ++++++ cell_array.m | 31 ++++++++++++++++++ conditional_statements.m | 51 +++++++++++++++++++++++++++++ function_handles.m | 7 ++++ logic_datatypes.m | 17 ++++++++++ map_container.m | 45 ++++++++++++++++++++++++++ matrix_intro.m | 57 +++++++++++++++++++++++++++++++++ matrix_manipulation.m | 67 +++++++++++++++++++++++++++++++++++++++ matrix_reshape.m | 8 +++++ meta_functions.m | 29 +++++++++++++++++ multidimensional_arrays.m | 0 objects.m | 32 +++++++++++++++++++ scalar_types.m | 16 ++++++++++ string_operations.m | 58 +++++++++++++++++++++++++++++++++ struct_arrays.m | 29 +++++++++++++++++ tables.m | 0 try_catch.m | 0 tseries.m | 0 19 files changed, 481 insertions(+) create mode 100644 BasicClass.m create mode 100644 basic_casting.m create mode 100644 cell_array.m create mode 100644 conditional_statements.m create mode 100644 function_handles.m create mode 100644 logic_datatypes.m create mode 100644 map_container.m create mode 100644 matrix_intro.m create mode 100644 matrix_manipulation.m create mode 100644 matrix_reshape.m create mode 100644 meta_functions.m create mode 100644 multidimensional_arrays.m create mode 100644 objects.m create mode 100644 scalar_types.m create mode 100644 string_operations.m create mode 100644 struct_arrays.m create mode 100644 tables.m create mode 100644 try_catch.m create mode 100644 tseries.m diff --git a/BasicClass.m b/BasicClass.m new file mode 100644 index 0000000..fed3e1c --- /dev/null +++ b/BasicClass.m @@ -0,0 +1,25 @@ +classdef BasicClass + properties + Value {mustBeNumeric} + end + methods + % contstructor + function obj = BasicClass(value) + % obj is by default an instance of BasicClass, no need to assign + if nargin == 1 + obj.Value = value; + end + end + function r = roundOff(obj) + r = round([obj.Value],2); + end + function r = multiplyBy(obj,n) + r = [obj.Value] * n; + end + % operator overloading + function r = plus(o1, o2) + % [x.Value] used to support object arrays by default + r.Value = [o1.Value] + [o2.Value]; + end + end +end \ No newline at end of file diff --git a/basic_casting.m b/basic_casting.m new file mode 100644 index 0000000..dc0a7f7 --- /dev/null +++ b/basic_casting.m @@ -0,0 +1,9 @@ +clear + +assert(str2double('3') == double(3)); +assert(str2double('3.4') == double(3.4)); +assert(all(str2num('1 2 3') == [1 2 3 ])); +assert(isnan(str2double('1 2 3'))); +assert(all(int2str(1.2) == int2str(1))); +assert(all(num2str(1.2) == '1.2')); +assert(all(mat2str([1 2 3]) == '[1 2 3]')); \ No newline at end of file diff --git a/cell_array.m b/cell_array.m new file mode 100644 index 0000000..eafae66 --- /dev/null +++ b/cell_array.m @@ -0,0 +1,31 @@ +clear + +% cell arrays are like n-dimensional arrays, but have hetergeneous +% data-types inside + +a = {'p'}; +v = {1 'a'}; +D = {1 2; 't' [1 2]}; + +% like vectors, scalars, and matrices, cell arrays are two-dimensional +% by default +assert(ndims(a) == 2); +assert(ndims(v) == 2); +assert(ndims(D) == 2); + +% indexing a cell array follows the same rules, and returns another cell +% array (like indexing a matrix returns a matrix, remember that scalar +% are 1x1 matrices +assert(all(size(D(2, 2)) == [1 1])); + +% to unbox the cell values, index with {} instead of () +% this will return a matrix instead of a cell +assert(D{2,1} == 't'); +assert(all(D{2, 2} == [1 2])); + +% equality check: +cs = {1+3 2}; +assert(isequal(cs, {4 2})); + +% convert cell array to standard array +assert(isequal(cell2mat(cs), [4 2])); \ No newline at end of file diff --git a/conditional_statements.m b/conditional_statements.m new file mode 100644 index 0000000..896bacb --- /dev/null +++ b/conditional_statements.m @@ -0,0 +1,51 @@ +% if statement +a = randi(100); + +if a > 66 + disp('a is greater than 66') +elseif (a > 33) && (a <= 66) + disp('a is between (33, 66]') +else + disp('a is between 1 and 33') +end + +% switch/case +choices = ['A', 'B', 'C', 'D']; +idx = mod(a, numel(choices)) + 1; + +switch choices(idx) + case 'A' + disp('A choosen') + case 'B' + disp('B choosen') + case 'C' + disp('C choosen') + otherwise + disp('Invalid choice') +end + +% for statement + +% this is intuitive +for i = 1:3:10 + disp("i = " + string(i)); +end + +% this as well +v = [1 2 3]; +for el = v + disp("el = " + string(el)); +end + +% when you iterate on a matrix, you iterate by columns +A = [1 2; 3 4; 5 6]; +for column = A + disp(column); +end + +% to iterate by rows +for row = A.' + disp(row); +end + +% while loop: too easy \ No newline at end of file diff --git a/function_handles.m b/function_handles.m new file mode 100644 index 0000000..7f4c8c7 --- /dev/null +++ b/function_handles.m @@ -0,0 +1,7 @@ +numbers = [1 2 3 4 5]; + +% @name_of_existing_function +arrayfun(@sqrt, numbers) + +% anonymous function +arrayfun(@(n) n*n, numbers) \ No newline at end of file diff --git a/logic_datatypes.m b/logic_datatypes.m new file mode 100644 index 0000000..389d8c9 --- /dev/null +++ b/logic_datatypes.m @@ -0,0 +1,17 @@ +clear + +a = true; +array_of_logicals = [1 2 3] == [2 2 4]; +array_of_logicals ~= [false true false]; %[false true false] +assert(all(array_of_logicals == [false true false])); + +true(1, 3); % = [true true true] + +islogical(true); % true +islogical([true false]); % true + +% logical not +assert(~true == false); + +% checking equality of complex types +res = isequal(eye(3), [1 0 0; 0 1 0; 0 0 1]); \ No newline at end of file diff --git a/map_container.m b/map_container.m new file mode 100644 index 0000000..eac8543 --- /dev/null +++ b/map_container.m @@ -0,0 +1,45 @@ +% a map is an instance of a Map class + +% creates an empty map +emptyMap = containers.Map; + +% .Count: total number of key/value pairs +assert(emptyMap.Count == 0); +% .KeyType: class of the key value +% by default set to 'char' +assert(isequal(emptyMap.KeyType, 'char')); + +% .ValueType: class of the values +% by default set to 'any' +assert(isequal(emptyMap.ValueType, 'any')); + +% create initalized map +% note: keys can only be +% - integers scalars +% - 1xN char arrays +% - double or single scalars +pairs = containers.Map({'Name', 'Msg'}, {"Enrico", "Hello"}); +assert(pairs.Count == 2); +assert(isequal(pairs.KeyType, 'char')); +assert(isequal(pairs.ValueType, 'any')); % this didn't change + +% size(map, 1) is equivalent to .Count +assert(pairs.Count == size(pairs, 1)); + +% size(map, 2) = size(map, 3) = ... = 1 (map is sort of nx1) +assert(size(pairs, 23) == 1); + +% size(map) returns [map.Count 1] +assert(isequal( size(pairs), [pairs.Count 1] )); + +% keys() returns the sorted keys as a cell array +assert(isequal( keys(pairs) , sort({'Name', 'Msg'}))); + +% values() returns the map values, sorted as the corresponding keys +assert(isequal( values(pairs), {"Hello", "Enrico"} )); + +% index map by key +assert(isequal( pairs('Msg'), "Hello" )); + +% change a value +pairs('Msg') = "World"; \ No newline at end of file diff --git a/matrix_intro.m b/matrix_intro.m new file mode 100644 index 0000000..4661df8 --- /dev/null +++ b/matrix_intro.m @@ -0,0 +1,57 @@ +clear + +% scalar and vectors are matrices +a = 13; +assert(a(1,1) == 13); + +v = [1 2 3]; % vectors are row vector by default +t = [4,5,6]; % can also use comma to separate values +assert(v(1,2) == 2); +assert(v(2) == 2); +t_col = t.'; % column vector given by transpose +assert(t_col(3, 1) == 6); + +% complex transpose (adjoint matrix) +s = [1+1i 3-1i]; +assert(all(s' == [1-1i 3+1i].')); + +% size() finds the matrix dimensions of something +assert(all(size(a) == [1 1])); +assert(all(size(v) == [1 3])); +assert(all(size(v') == [3 1])); + +% length() returns the largest dimension given by size() +assert(length(a) == 1); +assert(length(v) == 3); +assert(length(v.') == 3); + +% isempty() is equivalent to length(X) == 0 +assert(isempty(a) == false); +assert(isempty([]) == true); + +% ndims() is equivalent so length(size(v)) +% this proves that scalars and vectors are matrices +assert(ndims(a) == 2); +assert(ndims(v) == 2); +assert(ndims(v.') == 2); + +% create a 3x3 matrix: rows separated by ; +M = [1 2 3; 4 5 6; 0 -1 -2]; + +assert(M(2, 3) == 6); +all(M' == [1 4 0; 2 5 -1; 3 6 -2]); % all operates on the first dimensions + % returns [1 1 1]; +% check all elements (i.e. all dimensions) by doing +assert(all(M.' == [1 4 0; 2 5 -1; 3 6 -2], 'all')); +% can be done better by doing +assert(isequal(M.', [1 4 0; 2 5 -1; 3 6 -2])); + +% note: length on a matrix is not the number of elements +% but the size of the max dimension +assert(length(M) == 3); + +% numel() is equivalent to multiplying the entries given by size() +% returns the number of scalar elements +assert(numel(a) == 1); +assert(numel(v) == 3); +assert(numel(M) == 9); diff --git a/matrix_manipulation.m b/matrix_manipulation.m new file mode 100644 index 0000000..e098784 --- /dev/null +++ b/matrix_manipulation.m @@ -0,0 +1,67 @@ +clear + +a1 = [1 2 3]; +a2 = [4, 9, 10]; + +% create 3x2 matrix by joining columns +% two equivalent ways: +A = [a1.', a2.']; +A = horzcat(a1.', a2.'); +A = cat(2, a1.', a2.'); % 2 selects the dimension that varies + % which is the dimension along which it concatenates + % 2 == column + +% create a 2x3 matrix by joining rows +B = [a1; a2]; +B = vertcat(a1, a2); +B = cat(1, a1, a2); % columns stay the same + +% note: +assert(all(horzcat(a1, a2) == [1 2 3 4 9 10])); % not as above! + +% also, comparision of row and column vectors gives non obvious result: +assert(all(a1 == a2.' == false(3), 'all')); + +% ranges +assert(all(1:3 == [1 2 3])); +assert(all((1:3).' == [1 2 3]')); + +% non integer ranges +% default step is 1 +assert(all(1.5:3.5 == [1.5 2.5 3.5])); +% different step: note that 10 is included +assert(all(1 : 3 : 10 == [1 4 7 10])); +assert(all(1.3 : 2.2 : 5 == [1.3 3.5])); + +C = [A [2 9 8].']; + +% select one element +assert(C(2, 1) == 2); +% select element 1 and 3 on the second row +assert(all(C(2, [1 3]) == [2 9])); +% select element 1 and 3 on the first column +% note that the resulting entries are in a column vector +assert(all(C([1 3], 1) == [1 3].')); + +% select the whole third row: progressively smarter +assert(all(C(3, [1, 2, 3]) == [3 10 8])); +assert(all(C(3, 1:3) == [3 10 8])); +assert(all(C(3, :) == [3 10 8])); + +assert(all(C(:, :) == C, 'all')); + +% select the whole second column +assert(all(C(:, 2) == [4 9 10].')); + +% select the first and the third column, joining them +assert(all(C(:, [1 3]) == [1 2 3; 2 9 8].', 'all')); + + +% todo: linear indexing and logical indexing +% sub2ind ind2sub +assert(all(A(:) == [1 2 3 4 9 10].')); + +% remove elements from an array +D = [1, 3, 6, 2, 3, 1]; +D(D == 3) = []; % remove all threes +assert(isequal(D, [1, 6, 2, 1])); \ No newline at end of file diff --git a/matrix_reshape.m b/matrix_reshape.m new file mode 100644 index 0000000..570601d --- /dev/null +++ b/matrix_reshape.m @@ -0,0 +1,8 @@ +clear + +v = 1:12; + +% reshape v as 4x3 matrix +M = reshape(v, [4,3]); +% note: M(:) is a column vector +assert(all(M(:) == v.')); \ No newline at end of file diff --git a/meta_functions.m b/meta_functions.m new file mode 100644 index 0000000..912e970 --- /dev/null +++ b/meta_functions.m @@ -0,0 +1,29 @@ +clear + +A = [1 2 3]; +b = true; + +% print the list of variables in the workspace +who +% if saved to a variable, saves the variables as a nx1 cell +vars = who; + +% prints all variables along with class, size, byes, attributes +whos + +% prints info for a single var +whos A +% identify the type of a variable +class(A) +class(b) +c = int32(3); % class doesn't work with literals :( +class(c) + +% test for data type +isinteger(c) +isnumeric(A), isnumeric(c) +ismatrix(c) +isa(A, 'numeric') + +% find the file where a user or built-in function is defined +which eye; \ No newline at end of file diff --git a/multidimensional_arrays.m b/multidimensional_arrays.m new file mode 100644 index 0000000..e69de29 diff --git a/objects.m b/objects.m new file mode 100644 index 0000000..ffee69c --- /dev/null +++ b/objects.m @@ -0,0 +1,32 @@ +% instantiate an object of type BasicClass (see BasicClass.m) +obj = BasicClass; + +assert(isempty(obj.Value)); + +obj.Value = 3; +obj.Value = [3 4.5]; + +% methods can be called in two ways +roundOff(obj); +% or dot notation +obj.roundOff(); + +% use the constructor +v = BasicClass(42); +assert(v.Value == 42); + +% object arrays are presto supported +objs(1) = BasicClass(44); +objs(2) = BasicClass(33); + +% [objs.Value] expands to [objs(1).Value ...] +assert(isequal( [objs.Value], [44 33] )); + +% you can also do this with a cell array +assert(isequal( {objs.Value}, {44, 33} )); + +% operator overloading +obj + objs(1); + +% also works for object arrays +[objs] + [objs] \ No newline at end of file diff --git a/scalar_types.m b/scalar_types.m new file mode 100644 index 0000000..5c28226 --- /dev/null +++ b/scalar_types.m @@ -0,0 +1,16 @@ +clear + +% by default everything is double floating precision +a = 3; +assert(isequal(class(a), 'double')); + +% specify a different scalar type +b = int8(100); +assert(isequal(class(b), 'int8')); + +% also unsigned +c = uint16(291); +assert(isequal(class(c), 'uint16')); + +% a matrix of int32 +int32_matrix = int32([1 2; 3 4]); \ No newline at end of file diff --git a/string_operations.m b/string_operations.m new file mode 100644 index 0000000..f810f13 --- /dev/null +++ b/string_operations.m @@ -0,0 +1,58 @@ +clear + +% two types for representing text: +% 'char' arrays and 'string' arrays + +char_scalar = 'a'; +char_array = 'abc'; +% 'abc' is the same as ['a' 'b' 'c'] +assert(all(char_array == ['a' 'b' 'c'])); +assert(all(size(char_array) == [1 3])); + +char_matrix = ['abc'; 'def']; +assert(numel(char_matrix) == 6); + +% string arrays provide functions to deal with them +% this two are not equivalent! +string_scalar = "Hello World!"; % < 1x1 string array +string_array = ["Hello", "World"]; % < 1x2 string array +assert(all(string_scalar ~= string_array)); + +% convert a char array to a string +msg = string(char_array); +assert(ischar(char_array)); +assert(isstring(msg)); + +% convert a number to a char array (despite the name!!) +one = int2str(1); +pi = num2str(3.14); +arr = num2str([1 3]); + +assert(all(one == '1')); +assert(all(pi == '3.14')); +assert(all(arr == '1 3')); + +% convert something to a string +one_s = string(1); +pi_s = string(3.14); +arr_s = string([1 3]); +cell_s = string({1 10}); % cannot do this with num2str + +assert(one_s == "1"); +assert(pi_s == "3.14"); +assert(all(arr_s == ["1", "3"])); +assert(isequal(cell_s, ["1", "10"])); % note that the result is a string array + +% get a char array length +assert(numel('abc') == 3); % obvious +% get a string length: less obvious +assert(numel("abc") == 1); +assert(strlength("abc") == 3); + +% concatenate strings: lot of ways (char, strings, cell of strings... plus +% dimensionality) + +% basic way: +assert(isequal("Hello" + " World", "Hello World")); +% more correct (deals with char arrays and cell arrays of strings) +assert(isequal(append("Hello", ' ', "World"), "Hello World")); \ No newline at end of file diff --git a/struct_arrays.m b/struct_arrays.m new file mode 100644 index 0000000..0520ea1 --- /dev/null +++ b/struct_arrays.m @@ -0,0 +1,29 @@ +clear + +% create a struct array +patient(1).name = 'John Doe'; +patient(1).billing = 127.00; +patient(1).test = [79, 75, 73; 180, 178, 177.5; 220, 210, 205]; + +% add an entry to the struct array +patient(2).name = 'Ann Lane'; +patient(2).billing = 28.50; +patient(2).test = [68, 70, 68; 118, 118, 119; 172, 170, 169]; + +% creates a new records 'age'; this will be created in all the other +% entries; fields not specified here are set to [] +patient(3).name = 'New Name'; +patient(3).age = 21; + +% creates a new struct array with the same layout +customer(1).name = 'Enrico'; +customer(1).billing = 30.0; +customer(1).test = []; +customer(1).age = 25; + +% concatenates patient and customer to create a new struct array +v = [patient customer]; % or [patient, customer] + +% can also concatenate in a matrix layout: this create a 2x2 struct matrix +M = [patient(1:2); [customer patient(3)]]; +assert(all(M(2, 1).name == 'Enrico')); diff --git a/tables.m b/tables.m new file mode 100644 index 0000000..e69de29 diff --git a/try_catch.m b/try_catch.m new file mode 100644 index 0000000..e69de29 diff --git a/tseries.m b/tseries.m new file mode 100644 index 0000000..e69de29