% Everything after a percentage sign is ignored by MATLAB
% This is useful to make notes for yourself. 

%% A double percentage sign without spaces creates a cell
%Use cells to break up your code into meaningful segments, e.g.
% loading data, analyzing data, plotting data

%% After a double percentage (and a space), the text is bolded

%% We strongly recommend to start each file with a header
%What is this? (What does it do, assumptions, outputs)
%Who did it?
%How do I reach them?
%When? (Versioning) 

%% 0 Pretend header: Lab 1 - from 0 to 0.01
%Philosophy: MATLAB as a graphing linear algebra calculator
%You
%09/08/2016

%% 1 Arithmetic operations - everything works as you would expect

5 + 2 %Plus
5 - 2 %Minus
5 * 2 %Multiplication
5/2 %Division
5^2 %Exponentiation
5^0.5 %Square root

%Order of operations: Also everything as expected
(5 + 4/2)^2

%White space or - more neutrally - blank space: 
%Is ignored in MATLAB (not Python)
5 + 2
5 +              2
5 +        2
5 +                              2


%% Variables - in MATLAB, we store values (usually numbers) in these
A = 5
B = 2.5
C = 2*B
D = 5 + 2

% = equality sign looks suspiciously like testing for equality
% but is actually an assignment operator. It takes whatever is on the
% right side and overwrites the left side

%Testing for equality: 2 equal signs: ==
A == A
A == B
A == C

%How to access variables, say I want to know what is in D. 
%In case I forgot
D %Just type the variable name

%Variable names: What can you name variables?
%Can be anything you want, BUT must start with a letter
%cannot have a white space in it and ideally should not
%collide with a pre-existing function. 
%What should you name them? Something descriptive
%We recommend camelCase - every new word is capitalized for parsing
%This is superior to underscores, which are ugly.
numParticipants = 500; %More power

%What is ans?
%ans is a temporary variable that MATLAB creates whenever
%you do not explicitly ask for a left side variable to 
%assign whatever you do to. It has to go somewhere
%It is overwritten every time you make a new command.
%So this is not for permanent storage, but can be useful
%for iterative procedures. You *can* compute with it.
5 + 5 %ans will become 10
ans + 5 %ans will become 15
ans + ans %ans will become 30

%% 3 Functions - if variables are your matter, and forces are your operators, these are they

%Recall that we did square rooting with exponents
9^0.5 %Exponent way
sqrt(9) %Functional - all arguments to functions are denoted by parentheses ()

abs(2)
abs(-2)

%help abs is the quick and dirty inline help
%doc abs brings up the relevant entry in the MATLAB documentation
%Finally, if you know you need help, but don't even know where to begin to
%look, click on the function browser and search for keywords.

%Functions can be concatenated, chained, nested
sqrt(-3) %This will throw us on the complex plane
sqrt(abs(3)) %Let's keep it real
%Which function does MATLAB execute first? The innermost nested one

rand(1) %Pull 1 random number from 0 to 1 out of a hat. A well mixed urn.
%Every time you execute this, you'll get a new number, but if you all
%share the same seed (or MATLAB license), the sequence will be the same!

abs(-2) %2, as you would expect
abs = abs(-4) %Say I want to store this as a constant
%abs(-2) %Now commented out so that running this doesn't crash the script

%We can fix our mistake by calling clear
%As in clear abs
%Unless we overwrite clear also, in which case we have to right-click and
%delete it in the workspace itself.
%clear all deletes all variables from the workspace
%As does clear, since a couple of versions
clear all

which numParticipants %If you are unsure of whether it exists

%The most common problem I see is by calling something "size"

%We might as well talk about formatting vs. precision
%Formatting controls how you see the output without changing the internal
%representation
%Precision changes how MATLAB represents a number internally. There is an
%inherent tradeoff between resolution and memory demands.
A = sqrt(7) %Assign square root of 7 to variable A
format long %16 after-digit numbers
A
format short %4 after-digit numbers
A
format bank %2 after-digit numbers
A
format rat %rational approximation (as a fraction)
A
format long %back to long
%NONE of these change how MATLAB represents the numbers internally
%Double vs. single precision (MATLAB default: double)

B = 2^127+1 %A big number - but not that big to be represented as a double. Double = 8 bytes = 64 binary digits. Switches.
C = single(B) %Setting precision of C to single, with value B. single = 4 bytes = 32 binary digits or switches

B = 2^128 %A number that is just 1 larger
C = single(B) %But it can no longer be represented as single

%Both single and double precision can accomodate numbers that are larger
%than anything you are likely to encounter in neuroscience. However, some 
%precisions are rather limited, e.g. if you want to represent a number with
%1 byte = 8 bits = 8 switches = 2^8 = 256.
B = 256
C = uint8(B) %unsigned integer 8 bit - can represent 256 states from 0 to 255
%255 is the infinity of uint8, you can not represent numbers larger than
%that.
%Also, only integers - if the result is irrational (or not integral), it
%simply rounds:
uint8(sqrt(7))
%The benefit? Memory!

%That's it for now about variables and how they are represented

%% 4 Vectors! Vectors are stacks of numbers

%Row vector with 5 elements
A = [1, 2, 3, 4, 2] %Sets of numbers to be assigned to a variable all at once are denoted by SQUARE brackets []
%The comma denotes horizontal concatenation of numbers (to create our row
%vector), it is implied - if you don't put anything, MATLAB will assume a
%comma

%Column vector with 3 elements
B = [3; 5; 4] %Semicolon HERE means vertical concatenation

%Dimensionality can be assessed by looking at the workspace
%OR by calling the size function
size(A)
size(B)
%Convention: Rows are first, columns are second, sheets are third and
%workbooks are 4th and so on. You can have as many dimensions as you want.
%But a vector has 2 and one of them is of dimensionality 1. 
%It's a stack of numbers. 

%Now you know why you should never call any variable "size", no matter
%how tempting it might be.

%Converting row vectors to column vectors and vice versa
%Transpose!
transpose(B)
B'

%Vector operations: Most functions in MATLAB operate on vectors natively
mean(A)
mean(B)
sum(A)
sum(B)

%We need to talk about the echo
A = [1:1000] %This creates a vector from 1 to 1000. Colon means "from, to"
B = [1:1000]; %Semicolon turns the echo off. It still executes the command, but you no longer see immediate inline output

%The third function of the semicolon in addition to vertical concatenation
%of numbers and echo off (echo is on by default) is concatentation of
%inline commands
C = [1; 2; 3]; D = sum(C); %All the semicolons used here have different meanings
%As you see in C, some semicolons even serve multiple functions!

%% 5 Matrices - stacks of vectors!
%Matrix creation
A = [1 2 3;4 5 6;7 8 9] %Stacking row vectors
size(A) %Dimensionality
numel(A) %Number of elements

%Accessing elements of matrix elements and reassinging them
%I want to access the 2nd row
A(2,:) %Colon without arguments means "all"
%I want to access the last 2 elements of the 3rd row
A(3,2:3)
A(3,2:end) %As you see, there are many ways to do this
%I want to access the first column
A(:,1)
%I want to access the element in the 3rd column and 3rd row
A(3,3)
%I want to reassign the number 55 to that element
A(3,3) = 55;
%I want to delete the 3rd column
A(:,3) = []; %This [] is the empty set, it means "delete" here 
%You could also reach in and define a subset
%A = A(:,1:2)
%I want to "vectorize" (flatten) matrix A and assign it to B
B = A(:) %This destroys the substructure of A and just creates a vector with the same elements

%MATLAB operates column-wise by default. If you want the elements of the
%vectorized matrix in row-order, you have to transpose first.
B = A';
C = B(:)

%If you want the *result* to be a row vector, you need to transpose
%*afterwards*

%Operations on matrices work seamlessly. This is literally one of MATLABs
%greatest strengths. They are as fast as can be.
%Why? Because MATLAB is slow because it reads and interprets commands line
%by line. BUT a single matrix operation is a single line. No matter how big
%the matrix is. 
mean(A) %Without arguments, this is the column-wise mean.
mean(A,2) %But you can always say which dimension of the matrix you want to operate on, this gives you the row-wise mean

%Again, MATLAB does everything column-default unless you tell it otherwise

%MATRIX addition
A = [1 2 3;4 5 6;7 8 9] %Stacking row vectors
B = ones(3) %This creates a 3x3 square matrix of ones
C = A + B %This works as long as they have the same dimensionality

%MATRIX multiplication 1: Inner product
%Let's say we have an electrode array on every C elegans neuron
%C elegans has 302 neurons. We all know them by name.
%Let's also pretend that these neurons fired action potentials.
%We want to know the expected value of action potentials at any given 
%time in the C elegans brain, if C elegans had a brain. 
%Say there are 7 cell classes. 
neuralFiringRates = [0.5 1 2 4 8 0.25 3]; 
numberOfNeurons = [45; 15; 35; 20; 50; 36; 101]; 

%Verify that you have accounted for all the neurons
totalNumberOfNeurons = sum(numberOfNeurons)
expectedSpikeCount = neuralFiringRates*numberOfNeurons

%So the inner product gives us the expected number of spikes
%in a single line, regardless of size of nervous system!
%What is it doing under the hood? 
%2 steps: Element-wise multiplication, then summation
%Element wise multiplication - the kind you know from high school
%is denoted as .*
elementWiseMultiplication = neuralFiringRates.*numberOfNeurons'
innerProduct = sum(elementWiseMultiplication)

%Last thing for today: Holes in array
%Nature abhors a vacuum, MATLAB abhors holes in arrays
rtP1 = [1000 1500 500 1200] %reaction times per trial, participant 1
rtP2 = [2000 1700 3000 700] %same, participant 2
RTs = [rtP1; rtP2] %Array of RTs where columns are trials and rows are participants

mean(RTs,1) %Per trial mean
mean(RTs,2) %Per participant mean

%What if the 2nd participant missed the last trial?
%rtP2 = [2000 1700 3000] 
%RTs = [rtP1; rtP2] 

%This throws an error, because MATLAB does not know how to stack
%the vectors, which trial is missing. We have to give it a placeholder
rtP2 = [2000 1700 3000 nan] 
RTs = [rtP1; rtP2] 

%NaN is not a number but is treated by MATLAB as such
isnan(rtP2) %tests for whether something is a nan
isnumeric(rtP2) %test for whether something is a number

%This has implications for the mean: As soon as a single nan
%is involved, the result will be a nan. 
mean(RTs,1)
mean(RTs,2)

%Once you have nans, to represent the holes, you can call functions
%that can handle it:
nanmean(RTs,1)
nanmean(RTs,2)

%Or you could delete the offending trial (or participant)
RTs(:,4) = [];
mean(RTs,1)
mean(RTs,2)
