clear all; clc

%% 1 Datatypes

% Declare and assign variable a 
a = 3

%% 

% Which is the datatype of a?
class( a )

%% 1.1 Logical

clc

% Define a as logical true (true is actually a function!)
a = true

%%

% Define a as logical false (false is actually a function!)
b = false

%%

% Use the logical constructor
c = logical( 1 )

%%

% Everything ~= 0 is casted to logical 1 (true)
d = logical( 3 )

%%

% We can test whether a variable is of class logical with islogical()
islogical( a )

%% 1.2 Char

clc

% This is a char
a = 'a'

%%

% This is actually a char array
b = 'This is a character array (a so-called string)'
length( b )

%% 1.3 Integers

clc

% Minimum and maximum values of the unsigned integer 8 datatype
intmin( 'uint8' )
intmax( 'uint8' )

%%

% You can create numbers which are of different type than double
a = int16( 1024 );

%%

% What happens at range endpoints?
a = uint8( 150 );
b = uint8( 130 );
c = a + b

%%

% What happens to datatype mismatches?
a = int8(-120 );
b = uint8( 100 );
c = a + b

%%

% You can test for a variable being of a given datatype
isa( a, 'uint8' )

%% 1.4.1 Real numbers

clc

% You can create single-precision numbers
a = single( 1.75 )

%%

% What is the precision of single vs double?
eps( single( 1 ) )
eps( double( 1 ) )

%%

% Round-off error example
1 - 3 * ( 4 / 3 - 1 )

%%

% Also real numbers have a minimum and a maximum
realmin
realmax

%% 1.4.2 Complex numbers

clc

% What is i?
sqrt( -1 )

%% 

% Examples of complex numbers
a = 1 + i * 3;
b = 2 - 5i;
c = single( b );

%% 1.4.3 Special values

% Plus infinite
a = 1 / 0

% Minus infinite
b = -1 / 0

% Not-A-Number
c = 0 / 0

%% 1.5.1 Building structures using assignment statements

clc

% Build a structure one field at a time
patient.name = 'John Doe'

%%
patient.billing = 127.00

%%
patient.test = 79

%% 1.5.2 Building structures using the struct function

patient = struct( 'name', 'John Doe', 'billing', 127.00, 'test', 79 )

%% 1.5.3 Accessing structure fields

patient.name

%% 1.5.4 Nesting structures

clc

% We create a structure and add it as a field to another structure
name.firstName = 'John'; 
name.familyName = 'Doe'; 
patient.name = name;

patient

patient.name

%% 1.6 Cell
% We'll see it as cell array

%% 2 Arrays

clc

%% 2.1 1-dimensional numeric arrays: vectors

%% 2.1.1 Row vectors

% A row vector with three components (elements)
v = [ 1 3 sqrt( 5 ) ] 

%% 

% The length of an array is the number of elements along its largest
% dimension
length(v)

%% Operations between vectors

clc

% Let's define two vectors to work with
a = [ 1 2 3 ]
b = [ 3 2 1 ]

%%

% Vector addition
a + b

%%

% Vector subtraction
a - b

%%

% Vector elementwise power
a .^ b

%%

% Vector elementwise multiplication
a .* b

%%

% Vector elementwise division
a ./ b

%%

% Vector MATRIX multiplication - what happens?
a * b

%% Operations vector-scalar

clc

% Redefine a (in case...)
a = [ 1 2 3 ]

%%

% Vector-scalar addition
a + 1

%%

% Vector-scalar subtraction
a - 1

%%

% Vector-scalar (elementwise) multiplication
a .* 2

%%

% Vector-scalar (elementwise) division
a ./ 2

%%

% Vector-scalar multiplication
a * 2

%% 2.1.2 Column vectors

clc

% How to create a column vector
c = [ 1; 3; sqrt(5)] 

c2 = [ 3 
    4
    5]

%%

% How do we distinguish between row and column vectors?
size( [ 1 2 3 ] )

size( [ 1; 2; 3 ] )

%% Which operations are allowed between row and column vectors?

clc

% Let's define two vectors to work with
a = [ 1 2 3 ]
b = [ 1; 2; 3 ]

%%

% Can we sum them?
a + b

%%

% Can we multiply them element by element?
a .* b

%%

% Can we matrix-multiply them? 
a * b

% (This is an scalar or inner product)

%%

% Can we matrix-multiply them in the other direction?
b * a

% (This is a matrix multuplication or outer product)

%% 2.1.3 The colon operator

clc

% How does the colon operator work?
3 : 7

%%

% It can take an optional step parameter
0 : 0.5 : 2

%%

% One can also create decreasing sequences, provided the step is negative
2 : -0.5 : 0

%%

% What happens here?
a = 7 : 3

%% 2.1.4 Slicing

clc

% Let's create a vector to work with
a = 2 : 2 : 20

%%

% Slicing means extracting a portion of an array
a( 5 : 7 )

%% Try: extract every third element of the vector a = 2 : 2 : 20

% You do it!

%% 2.1.5 Transposing

clc

% Let's create a vector to work with
a = [ 1 2 3 ]

%%

% Transposing turns a row vector into a column vector (and viceversa)
a'

%% 2.1.6 Plotting vectors

% We will see more plotting in session 4. This shows how MATLAB function
% work on arrays natively

% We create some x values...
N = 50;
h = 1 / N;
x = 0 : h : 1;

%%

% ... and some y values to plot
y = sin( 3 * pi * x );

%%

% And now we plot them
plot( x, y, 'bo-' )
hold on

%% Try: N = 10

% What happens if we reduce N to 10?

% We create the new x...
N = 10;
h = 1 / N;
x = 0 : h : 1;

%%

% ... and the new y
y = sin( 3 * pi * x );

%% 

% And plot
plot( x, y, 'ro-' )

% What happened?

%% 2.1.7 Finding elements in an array

clc

% Again, we create a vector to work with
a = 1 : 10

%%

% We use relation operators to test an array
b = a > 5


%%

% We can use the find function to return the positions of the true elements
% in the vector
find( b )

%%

% We can of course skip one step
find( a > 5 )

%% Elementwise logical operators &, | ~

clc

% Our usual vector...
a = 1 : 10

%%

% Introducing elementwise logical operators...
b = a > 5 | a == 3

%% Try: Find and display all numbers between 1 and 100 that are even and 
% divisible by 3 but not by 4.

% You do it!

%% 2.2 2D arrays (matrices)

clc

% Arrays can be extended into two dimensions
A = [ 5 7 9; 1 -3 -7 ]

%%

% There are some handy function to create matrices
Z = zeros( 10, 5 )

%%

O = ones( 10, 5 )  

%%

I = eye( 5 )

%%

R = randn( 1000, 1000 );

%% Exercise: Construct a 1000 x 1000 matrix with entries sampled from a 
% normal distribution with mean = 25 and standard deviation = 5.

% You do it!

%% Matrix operations

clc

% We create two matrices to work with
A = randn( 3, 2 )
B = randn( 2, 5 )

%%

% Matrix multiplication
C = A * B

% What is the size of C?
size( C )

%%

clc

% Back to the inner product
a = 1 : 3
b = a'

C = a * b

%% 2.2.1 Transpose of a matrix

clc

% Matrix transposition swaps columns and rows
A = [ 1 2 3; 4 5 6 ]

A'

%% 2.2.2 Extracting bits of a matrix (slicing)

clc

% We create a matrix to work with
I = [ 1 2 3; 4 5 6 ]

%%

% Getting a single element from a matrix
I( 1, 1 )

%%

% Reading and writing to a matrix
I( 2, 3 ) = I( 1, 1 ) + 2 * I( 2, 2 )

%% Colon notation

% As for vectors, the colon notation is useful for matrices as well
I( 1 : 2, 2 : 3 )

%% 

% Extract full column
I( :, 1 )

%%

% Extract full row
I( 1, : )

%%

% Whole matrix
I( :, : )

% This is the equivalent of just I, so you'll never use this notation

%% 2.2.3 Iterating over arrays

clc

% MATLAB iterates over arrays in a different way than other programming
% languages

% Let's create two matrices to work with
A = rand( 5000, 5000 );
B = rand( 5000, 5000 );

% MATLAB works by VECTORIZING the code, i.e. by abstracting away the
% concept of iteration
tic
C = A + B;
toc

%%

% Other programming languages will force you to use loops to implement the
% same. MATLAB can also do it, but it will be significantly slower than the
% vectorized approach
C = zeros( size( A ) );
tic
for i = 1 : size( A, 1 )
    for j = 1 : size( A, 2 )
        C( i, j ) = A( i, j ) + B( i, j );
    end
end
toc

%% 2.3 Multidimensional numeric arrays

% They are a straightforward extension of the 2D case, so we don't treat
% them here.

%% 3 Structure arrays

clc

% We create a patient by assignemnt
patient.name = 'John Doe';
patient.billing = 127.00;
patient.test = 79

%%

% Now we add a second one - we created an array of structures
patient(2).name = 'Ann Lane';
patient(2).billing = 28.50;
patient(2).test = 68

%%

% As you expand the structure, MATLAB fills in unspecified fields with 
% empty matrices 
patient(3).name = 'Alan Johnson';

patient(3)

%% 

% Field sizes do not have to conform for every element in an array
patient(3).test = [ 85 123 12 ];

patient( 2 )
patient( 3 )

%% 3.2 Building structure arrays using the struct function

clc

% Using the "colon" syntax
weather( 1 : 3 ) = struct( 'temp', 72, 'rainfall', 0.0 )

%%

% Using the repmat "trick" (older MATLAB versions?)
weather = repmat( struct( 'temp', 2, 'rainfall', 0.0 ), 1, 3 )

%%

% Using the cell array syntax
weather = struct( 'temp', { 68, 80, 72 }, 'rainfall', { 0.2, 0.4, 0.0 } )

%% 4 Cell arrays

clc

A = { [ 1 4 3; 0 5 8; 7 2 9 ], 'Anne Smith'; 3 + 7i, -pi : pi / 4 : pi }

%% 
clear A

%% We can also create a cell array one element at a time

A( 1, 1 ) = { [ 1 4 3; 0 5 8; 7 2 9 ] }

%%
A( 1, 2 ) = { 'Anne Smith' }

%%
A( 2, 1 ) = { 3 + 7i }

%%
A( 2, 2 ) = { -pi : pi / 4 : pi }

%%

% You access the content of a given position in the cell array ith the {}
% notation:
A{ 2, 1 }

%%

% If you assign data to a cell that is outside the dimensions of the 
% current array, MATLAB automatically expands the array to include the 
% subscripts you specify. It fills any intervening cells with empty 
% matrices.

A( 3, 3 ) = { 5 }

%%

% All the steps so far could have been done with the {} notation:
A{ 4, 4 } = 7

%% 

% Slicing must use the () notation
A( :, 1 )

%% 5 Function handles

s = fminsearch( @(x) sin( x ) + cos( x ), 5 )
