%% Introduction to MATLAB
% As students you are entitiled to download the desktop version or exploit the online version of MATLAB.
%% Basic Commands
%
%% Naming variables
% We can store the results of a computation into a variable

x = 3 * 4

% In this instruction the assignment operator (=), assigns the the expression 3 * 4 to the variable x.
% You can now see the variable that you have created in the Workspace panel.
% Notice that the assignment result is displayed after the instruction execution.
% To avoid displaying the results, use a semicolon (;) at the end of the instruction.

y = x / 2;

% You can see that the result has not shown, but the variable appears in the Workspace panel.
%% Tip
% You can name the variables however you like as long as they start with a letter and contain only letters, numbers, and underscores (_).
% However, having meaningful variables allow you to read better the code. Also, by using comments (%) you can provide a description of your variables and, generally, of your codes.

% b = rectangle base
% h = rectangle height
b = 10; 
h = 2;
rectangle_area = b * h

% Notice that the MATLAB variables are case sensitive.

a = 5;
A = 8;

% As you can see, two variables appear in the Workspace.
%
%% Saving and loading variables
% You can also save your variables by using the save command.

save a

% You can also give a customized name to the file containing one or more of your variables.

save('all_the_lowercase_variables.mat', 'x', 'y', 'b', 'h', 'a')
% You can also use the save function with the following syntax
save x.mat x

% In some cases you may want to clear the Workspace without going the hard way (closing the program and restarting it).
% You can use the clear function to do so.

clear

% You can also clean the Command Window by using the clc function.

clc

% Afterwards, you can recall the variable you have saved before by using the load command.

load all_the_lowercase_variables.mat

% You can also specify the variables you want to load.

clear
load all_the_lowercase_variables.mat x y
% You can also use the load instruction with the following syntax
load("all_the_lowercase_variables.mat", "h")

% You can display the content of the Workspace by using the whos command.

whos

% By default, MATLAB stores all numeric variables as double-precision values (64 bits).
% However, numeric variables can have different precisions.

clear
a = 1;
% single-precision
b = single(a);
% 8-bit integer
c = int8(a);
whos

% You can also have different type of variables, without having to declare the variable type explicitly.

clear

% integer variable
iv = 2022;
% real variable
rv = 2e-5;
% complex variable
cv = 3 + 4i;
% string
str = "Multimedia Data Processing";

whos

%
%% Vectors and matrices
% As we have seen in the Introduction, MATLAB bases its functionalities on matrices.
% All the MATLAB variables are actually arrays.

clear
clc

% scalar
s = 2
% row vector
rv1 = [1 2 3 4]
rv2 = [1, 2, 3, 4]
% column vector
cv1 = [5; 10; 15; 20]
% matrix
M = [1 2; 3 4; 5 6]

% The : operator allows us to produce vectors containing evenly-spaced numbers.

v1 = 1:5

% You can see that we have generated a vector that contains the numbers from 1 to 5 with a default spacing of 1.
% We can also define different spacing.

v2 = 1:0.5:5

% Now we have a vector that contains the numbers from 1 to 5, but with a spacing of 0.5.
% If you know the specific number of elements you want in a vector, you can use the linspace function.
% How does the linspace function work? We can assess this information by using the doc or help commands.

doc linspace
help linspace

% The doc command opens the MATLAB documentation, while the help command reports an extract of the documentation for the specified function in the Command Window or in the live script output section.
% If you do not know exactly the name of the function you are interested in, but you know the functionality that you are searching for, you can use doc with some keywords.

doc linear spacing vector

% Now that we have seen how the linspace function works, let's use it to create a vector that starts from 0 goes to 1 and has 10 elements.

lv = linspace(0, 1, 10)

whos lv

% You can also use the : operator and the linspace function to create column vectors, by transposing (') their results.

c1 = (1:4:40)'
c2 = linspace(1, 2, 5);
c2 = c2'

%
%% Array creation functions
% You can also create arrays by using MATLAB native functions.

clear
clc

% Create a random matrix
doc rand
m1 = rand(5)
m2 = rand(2, 4)

% Create a matrix of 1s
m3 = ones(5, 3)

% You can also check the dimension of an array by using the size function.

size(m2)

%
%% Indexing and modifying arrays
% You can extract values from an array by indexing them, i.e., referring to the array elements using their position.

% Find the value of the array m2 element in the second row, third column
m2(2, 3)
% Find the last column values
m2(:, end)
% Find the values in the last row between column 2 and the penultimate column
m2(end, 2:end-1)

% You can also define an array on indexes to extract specific values.

idx_row = [2 4 5];
idx_col = [1 3];
m3(idx_row, idx_col)

% You can change specific values of an array.

arr = [2 4 5 8 10]
arr(2) = 6

% You can also make operations between arrays.

price = [23 21 21 24 25];
increase = 30;
increase_per_article = [2 7 10 3 4];

% Sum/substract array with a scalar
price_increase = price + increase
% Multiply/divide array by a scalar
price_times_2 = price * 2;

% Sum array of the same sizes
price_increase_differentiated = price + increase_per_article
% Multiply/divide array elementwise 
strange_price = price ./ increase_per_article

% You can also use some other operators on the arrays.

N = rand(6);

% Matrix transoponse
N'
% Sum the matrix columns
sum(N)
% Find maximum value of each column 
max(N)
% Do you want to find the minimum value of each row?
min(N, [], 2)
% Find the mean of each column
mean(N)
% Find the standard deviation of each column
std(N)

P = rand(6);

% Sum the matrices
N + P
% Muliply them
N .* P
% Make N power of P
N .^ P

% You can also concatanate arrays, but be careful! You should pay attention to their size.

NP = [N P]
NP = [NP; NP]
NP = [NP; rand(1, size(NP, 2))]

% Find the maximum values of NP 
[vNP, iNP] = max(NP)

% There are also some special matrices. We have seen the function that allow us to generate a random matrix or a matrix containing only 1s.
% How do we obtain a matrix of 0s and an identity matrix?
%
%% Plotting data
% Two vectors of the same length can be plotted against each other by exploiting the plot function.

% Vectors
x = 0:0.01:1;
y = exp(x);

% Plot them
figure 
plot(x, y)
xlabel("x")
ylabel("y")
title("My first plot")

% You can also continue to work on the same plot by using the hold on function.
% Moreover, you can customize the line colors, style, width and so on. Use the MATLAB documentation to find out more on how you can manage your plots.

hold on

y2 = exp(2*x)
plot(x, y2, "r--", "LineWidth", 2)

% Add a legend
legend("exp(x)", "exp(2x)")

% Once you have done everything that you wanted to do on the plot
hold off

% Notice that you can have figures with different plots.

figure
subplot(1, 2, 1)
plot(x, y)
legend("exp(x)")
subplot(1, 2, 2)
plot(x, y2, "r--")
legend("exp(2x)")

%
%% Logical indexing
% A relational operator allows the comparison between two values.
% The relational operators are ==, >, <, and ~=.
% A comparison will always present a binary result, where 0 correspond to FALSE and 1 to TRUE.
% Let's see some examples.

x = 1;
y = 1;
z = pi;

x1 = x == 1
x ~= y
x < z
y > z

% Moreover, you can compare more values at a time.

v = rand(1, 5)
v > 0.5

% You can see that we have obtained a logical array.
% Can we use it to index data in our arrays?

v(v > 0.5)

% The answer is "yes". As you can see, we have been able to extract all the values of v that are greater than 0.5.
% We can also decide to take the values selected through the logical indexing and change them.

v(v > 0.5) = 0

%
%% Logical operators
% You can use the logical operators & (AND) and | (OR) to combine logical comparisons.

v1 = [10 1 8 43 5 2];
% Find v1 values lesser than 10 and greater than 2
v1(v1 > 2 & v1 < 10)
% Find v1 values that are equal to 1 or greater than 10
v1(v1 == 1 | v1 > 10)

%
%% Programming constructs
% Concerning the programming constructs, we will see decision branching, for and while loops.
% Before diving into the code, let's go to the Lab01_IntroductionToMATLAB.pdf slides.
%% Decision branching

clear 
clc

a = 144;
b = -15;

% Play around with c
c = a;

% Decision branching
if c > 0
    disp(sqrt(c))
elseif c < 0
    disp(abs(c))
else
    disp(["c = " c])
end

%% For loop

d = 0;
for i = 1:a
    d = d + i;
end

%% While loop

e = 0;
j = 1;

while j 
    if e > 10 
        j = 0;
    end
    
    e = e + 3;
end

%
%% Conclusion
% We have seen the MATLAB interface, the basic commands, how to work with arrays, some functions, plots, logical indexing and operators, and some programming constructs.
% Now its your turn!
% Go to the course elearning page and try to solve the proposed exercises (practice01_intro.mlx).
%