% Matlab Basics

%% Matlab Window

% Command Window: Here you can type commands that get inmediately executed,
% but they are not saved in a file. It also displays several kinds of
% ouput.

% Workspace: An overview of all variables in the memory. Double clicking on
% a variable opens the Variable editor.

% Variable Editor: allows to see (and in some cases change) the variable’s
% value(s).

% Command History: List of recently used commands in the command window.
% You can double-click on them to execute them again.

% Current Directory: The directory where you currently are. Note that you
% need to be in the directory of a certain file in order to execute it.

% Current Folder: Displays all the files of your current directory.

% Editor:  This is a text editor to write your own Matlab programs.

%% Editor 

% Certain commands get different colors, and loops get indented 
% automatically.

% Each command goes into a single line. If you want to spread commands over 
% several lines, you have to tell Matlab by putting a '...' at the end of 
% the respective line. 

% You can also add comments to your code. Comments are set by putting a 
% percent sign '%' in front. New sections are created by putting a double
% percent sign '%%' in front. They are not executed when your code is run 
% and appear in green font. Comments are very useful not only for 
% organizing your code, but to help others understand its structure. 

%%
% Running your code:
% You can run your whole program either from the editor by pressing 'F5' (Windows)  
% or from the Tab 'Editor', clicking on the button 'Run'.

% If you do not want to execute your whole code, but only parts, you can 
% select the code you want to run and press 'F9' (Windows).

%% Built-in help

help max        % Display help text in Command Window.
doc max         % Display reference page in Help browser.

%% Variables

% Numbers, vectors and matrices:
A = 3
B = 5
B = A*B

clear A B C     % Delete numbers A, B and C from your Workspace

A = [ ]         % Define empty vector / matrix
open A          % Open variable A in the Variable editor
A(1) = 1
A(2) = 2

clear A

A = [1, 2]

ATrans = A'

B = [1, 2, 3; 4, 5, 6]

clear A ATrans B

% Other type of variables:

% String variable
L = 'Lorem ipsum dolor sit amet'

% Cell array: data type with indexed data containers called cells, where 
% each cell can contain any type of data.
H = {'Lorem ipsum dolor sit amet'; 2}

% Structures: data type that groups related data using data containers
% called fields. Each field can contain any type of data.
S.field1 = 'Lorem ipsum dolor sit amet' % Field 1
S.field2 = 2 % Field 2

% Miscellaneous:

% List all created variables
who

% List whith extended info
whos

% Variable names in Matlab must start with a letter and can be followed by
% letters, digits, and underscores. Special characters or spaces are not 
% allowed, as is the case with Matlab keywords like end or if.

% Matlab is case sensitive, thus 'namevar' and 'NameVar' are different
% variables.

% If you do not assign your computations to a pre-specified variable, 
% Matlab automatically stores the last computation result in the variable 
% 'ans' in the Workspace.

% Finishing your commands with a semicolon ';' supresses the output in the
% Command Window.

% Use the format function to control the output format of numeric values 
% displayed in the Command Window. Note: The format function affects only
% how numbers are displayed, not how MATLAB computes or saves them.

format short

1/3

format long

1/3

%% Setting Path

% Search Path
% Generally, if you want to execute a function or access a file in Matlab,
% you must tell Matlab that this command or file exists, and where it is in
% your computer. 

% Showing (printing on screen) yout current working directory
pwd
cd

% Change Path 'by hand'
% cd('Your path')      % Uncomment this line to set manually your Path
% Example (Windows): cd('C:\Users\UC3M\MatlabBasics\')

% Matlab will be able to use all files and functions on your current
% working directory. However, suppose that you create a function (we will
% se how to this later) and you want to store that function outside your
% current working directory. That can be done by adding the folder with the
% desired functions/files to the Matlab Search.

% To do this, locate the folder that contains these files on the Current
% Folder window, right-click on its name and select 'Add [...] to % Search Path'

% Adding to the Search Path via the right-click option only adds to the 
% Search Path for your current Matlab-session. In contrast, the ’Set Path’ menu 
% option is more flexible and allows for storing the path for future 
% Matlab-sessions as well as automatically adding all subfolders of a
% directory.

% In general, you should reserve permanently adding folders to your Search 
% Path for packages like Dynare (to be seen during the course).

% After setting your working path, you can import data to Matlab or save
% files.

% Importing from .csv
%data1 = csvread('example.csv');

% Importing from .xlsx
%data2 = xlsread('example.xlsx', 1);

% Note that you can also import from different paths by specifying the
% complete path to your files (and without changing your current working
% directory)
%data1 = csvread('path of the .csv /filename.csv');
%data2 = xlsread('path of the .xls /filename.xls', 1);

% Finally, you can also generate a diary (similar to a .log file) which
% saves all the commands that you type in your session
diary mycommands.txt
A = A + 1;
diary off

%% Basic Operations
% Create matrices and vectors

A = zeros(3,3);
B = ones(3,3);
C = eye(3);
D = [A, C]; 
E = diag(A);
F = [1, 2, 3; 4, 5, 6; 7, 8, 9];
U = rand(3,3);              % Uniform random generator
N = normrnd(0,1,3,3);       % Normal random generator
SN = randn(2,3);            % Standard Normal

a = 0:0.5:10;
b = 1:10;
c = 10:-1:1;
d = linspace(0,10,21);
e = 5;

% Display variables in your workspace
B
display(B)
display B 
display('B')
G = [7, 2, 6; 3, 5, 8; 9, 1, 5];
G(1,:) % The colon means the whole row or column
G(:,1)
G(2,2)
G(5)
G([1 3],2)
H = G([1 3],2) %Extract elements from G 

% Operations
I = G+C;
J = A-C;
K = B*B;
L = G/e;
Gsquared = G^2;
Gscalarsquared = G.^2;  % The point is a scalar operator
M = B.*N;   % If the dimensions agree you can perform some scalar multiplication
N = exp(G); % Exponential over the scalars
O = log(B); % Same with logs (over the euler constant e)
Ginver = inv(G);
P = 1./G;
Gtrans = G';
Gtrans1 = transp(G); % Another way to transpose

% Logical (Boolean) operations:
% < less than
% > greater than
% >= greater than or equal
% <= less than or equal
% == equal
% ~= not equal
% & and, | or, ~not
% It returns 1 (True) or 0 (False) in the output

Q = Gsquared==Gscalarsquared;
R = Gtrans>=G;
S = (Gtrans>=G) & Gsquared==Gscalarsquared;

%% Functions
% Built-in functions 

% Some functions operate either over columns or rows of your matrices
MAXG = max(G,[],1)   % Find maximun of each column
MAXG = max(G,[],2)   % Find maximun of each row
SUM = sum(G,1)       % Cumulative sum of columns
SUM = sum(G,2)       % Cumulative sum of rows
MEAN = mean(G,1)     % Mean
MEAN = mean(G,2)
STDG = std(G,0,1)    % Standard deviation
STDG = std(G,0,2)

% Other functions operate directly over the whole matrix!
ABS_SN = abs(SN)
R = rank(G)
C = det(N)
[row column] = size(N)
EIGENVALUES = eig(N)

% Disecting built-in functions
type('mean') % You can get inside built-in function

% Anonymous functions.
% Function that is not stored in a program file. Once you define it, it is 
% only accesible within your code 

a = 1.3;
b = 0.2;
c = 30;
f1 = @(x) a*x.^2 + b*x + c;
f2 = @(z) 5*z^2;
f3 = @(x) x.^2;

f1(2)
f2(10)
f3(3)
f1(10)+f2(5)+f3(3)

% Non-anonymous function:
% Function that is stored in a program file. 

% Home > New Script. 
% The first line of the function file has to have the following structure:
% function output = name_of_the_function(input).
% You must save the file with the name 'name_of_the_function.m'

% Try this one:
% function sqval = sq(x)
% sqval=x.*x;
% end

% Call the function in your script: 
sq(2*ones(1,5))

%% Conditional statements

if rand >0.5
   disp('Pass');
else
   disp('Fail');
end

% Use elseif to include more conditions. 
% Conditional statements can be nested.

%% Loops
% Note: 'Ctrl+C' breaks the loop, which is important for infinite loops.

% For loop (Repeatedly execute the same lines of code a specific number of
% times)
iter1=10; % Number of iterations

for i=1:1:iter1 % 1st: Starting point, 2nd: Stepsize, 3rd: Finishing point
    AA(i,:)=[i, i^2] % For all the rows, we use i to create the values
end

% Nested For loops
iter2=3;
iter3=4;

for j=1:iter3  
    for i=1:iter2
        BB(i,j)=i+j
    end
end

% While loop (Repeatedly execute the same lines of code until a specific
% condition is satisfied)

k = 0;          % Define a counter for the number of iterations (optional)
crit = 0.01;    
init = 16;
while init >= crit     % Beak (Stop) condition
    init = init/2;
    k = k+1;
    disp(strcat('# Iterations:  ',num2str(k)))
end

% You can write For(While) loops with break conditions inside the loop 
% itself.

for i=1:10
    if i<5
        Z(i) = 1
        continue 
    elseif i==5
        Z(i) = 2           
    else 
        break % exit 
    end
end


%% Graphs

% Basic plot
y = randn(1,100);

figure;
plot(1:100,y,'r-','LineWidth',1);
title('Example 1')
xlabel('X-axis label')
ylabel('Y-axis label')
legend('Series 1')
print('-dpdf','first_plot.pdf')     % Save as .pdf
print('-djpeg','first_plot.jpg')    % Save as .jpg

% Two plots
z = randn(1,100);
figure;
hold on
xaxis=1:100;
plot(xaxis,y,'r-','LineWidth',1.5);
plot(xaxis,z,'b:','LineWidth',2); % We can also put them in the same plot function
title('Example 2')
xlabel('X-axis label')
ylabel('Y-axis label')
legend('Series 1','Series 2')
hold off

% Subplots;
figure;
title('Graph with two subplots')
subplot(1,2,1)      % (m,n,p): m by n plots, location p
plot(1:100,y,'r:','LineWidth',1);
title('First subplot')
xlabel('X-axis label')
ylabel('Y-axis label')
legend('Series 1')
subplot(1,2,2)
plot(1:100,z,'b--','LineWidth',1);
title('Second subplot')
xlabel('X-axis label')
ylabel('Y-axis label')
legend('Series 2')

% 3D plotting
k = (0:0.01:1)';
l = (0:0.01:1)';
alpha = 0.3175;
A = 2;
[K,L] = meshgrid(k,l);
Y = A.*K.^alpha.*L.^(1-alpha);

figure;
surf(K,L,Y)
xlabel('Capital') 
ylabel('Labor') 
zlabel('Output')
title('Cobb-Douglas Production Function')

figure;
contour(K,L,Y)
xlabel('Capital') 
ylabel('Labor')
title('Cobb-Douglas Isoquants')

%% Cleaning 
% Already seen how to delete some specific variables.

clearvars       % Clears ALL variables from the memory 
close all       % Closes all open figures
clc             % Clears the command window

% Is is good practice to start your programs with a clear all, because you
% want to avoid having holdovers from previous programs floating around in 
% the memory. 

%% Debugging

% In many cases you will make mistakes. Matlab provides a debugger to 
% trace out the problems. If you click on the black line to the right of 
% the line number, Matlab will set a breakpoint at this line. The
% breakpoint is shown by a dot.

% A breakpoint is shown as a red dot to the right of the line number. Now,
% when running your code, Matlab will stop before executing this line. This
% allows you evaluate your code line by line by pressing 'F10'. Whenever 
% you reach to a function, pressing 'F11' will allow you to open the source
% code of the function and continue debugging. Note: it must be a built-in
% function or a non-anonymous function.

%% Tips about efficiency in Matlab
% Obtained from: 'matlabtips.com'

% General tip: Always run the profiler (run and time) to check where are
% the inefficiencies of your code.

% 1. Vectorize your code, Matlab is made to do matrix operations.
% Loops are much slower (although it got much better in the last versions)

% This is much slower...
tic 
A=rand(100,1);
B=rand(100,1);
B=zeros(100,1);
for i=1:100
   B(i)=A(i)*B(i);
end
toc

% than this...
tic
A=rand(100,1);
B=rand(100,1);
B=A.*B;
toc

% Think harder, even when you think is impossible to vectorize, there maybe
% a way...

% This is much slower...
tic
A=rand(100,1);
B=rand(100,1);
for i=1:100
   if B(i)>0.5
      B(i)=A(i)^2;
   else
      B(i)=exp(B(i));
   end
end
toc

% than this...
tic
A=rand(100,1);
B=rand(100,1);
C=(B>0.5);
B=C.*(A.^2)+(~C).*exp(B);
toc

% 2. Pre allocation: it is not stricly required as other hard typed
% languages, but still useful:
clear y
% Bad:
tic
for i=1:10000000
   y(i)=exp(i);
end
toc

% Better:
clear y
y=zeros(10000000,1);
tic
for i=1:10000000
   y(i)=exp(i);
end
toc

% Best (by a little):
clear y
y(10000000)=0;
tic
for i=1:10000000
   y(i)=exp(i);
end
toc

% 3. Inline: Some builtin functions are made to be very general in the
% sense that they take your input no matter of what type and try to handle.
% This can be very ineficient:

tic 
A=rand(1000,1);
for i=1:10000
   b=mean(A);
end
toc

% Now take a look inside the function and take only the useful part:
type('mean')

tic
A=rand(1000,1);
for i=1:10000
   b=sum(A,1)/size(A,1);
end
toc

% 4. Matlab is a column-major order: It organizes the numbers in the memory
% by column, thus in nested loops always go column first. Check:

% Row first
tic
X=rand(100,100,2000);
for i=1:100
    for j=1:100
        X(i,j,:)=10*X(i,j,:);
    end
end
toc

% Column first
tic
X=rand(100,100,2000);
for j=1:100
   for i=1:100
      X(i,j,:)=10*X(i,j,:);
   end
end
toc