%% Down with LiveSript!
% Enough already. Time to break free.
%
%% How to write a function
% A function is an "operator", a "processor", a "device" that takes input, and produces output.
% A function is an "m-file", it is saved with the extension "*.m" in a folder where MATLAB can find it.
% Make a new directory somewhere, and start putting ALL of your functions in it. Tell MATLAB to look for any commands that you issue (to call your own functions) also into that directory, by issuing the command (in my case):

addpath('/Users/fjsimons/Dropbox/FRS124/MatlabS')

% Then, open up a brand new *.m file inside of that directory, and start typing.
%
%% Rules of the game
% Rule #1. A function is saved as an *.m file with the same name as how you want to call it. Hence, a function that will take numbers and compute their sum, which I want to call from the command line using the command (for example):

>> mysum(8,9)

% is going to need to be accessible as the file "mysum.m" in the path of directories that Matlab searches (see the section above).
% Rule #2. The first word inside the function *.m file (e.g., mysum.m) is the word, you guessed it:

    function

% Rule #3. The second thing inside the function *.m file will be how you want to collect output. Continuing on, for example:

    function s=

% Rule #4. The third thing is the function's name, again, the same name as how you save it. That is:

    function s=mysum

% Rule #5. The fourth thing is, between parentheses, the names (strictly internally used, local to the innards of your functions) of input you want ingested by your function. For example:

    function s=mysum(a,b)

% Rule #6. The fifth thing is, after a percentage sign, the function syntax and a manual of sorts. This is ABSOLUTELY required, and I ABSOLUTELY recommend doing it exactly like in this example (including starting directly on the next line after the function definition):

    function s=mysum(a,b)
    % s=MYSUM(a,b)
    %
    % Calculates the sum of the two input variables
    % 
    % INPUT:
    %
    % a     The first input variable, a single number
    % b     The second input variable, a single number
    %
    % OUTPUT:
    %
    % s     The sum of the first and second input variables
    %
    % EXAMPLE:
    %
    % d=8; e=9; t=mysum(d,e)
    
    % TESTED ON: 9.1.0.441655 (R2016b)
    % WRITTEN BY: fjsimons@princeton.edu, 03/15/2017

% Rule #7. And then, only then, do you start giving the instructions as to what the function should be doing. Leave a blank line. Then start commenting again, as in (picking up from above):

    % WRITTEN BY: fjsimons@princeton.edu, 03/15/2017
    
    % Here's the algorithm, we use the operator PLUS, via its symbol
    s=a+b;

% Rule #8. If you made it this far, you're practially done. Your function can be called from the command line, with inputs that are numbers (in this case); you can use type, which, and most importantly, help mysum (in this case), and then you can focus on writing functions that are of actual interest, as opposed to this example.
% Rule #9. Think about the function before you start typing. What does it need to do? Design the algorithm first. Every good function has three parts:
% 1/ Check and rearrange inputs. Reorganize if necessary (e.g. turn things into column vectors, to facilitate later operations).
% 2/ Do something to the inputs, i.e. the algorithm, the thing you write the function for.
% 3/ Check and organize outputs. By the way. Want to output more internal variables? Add them to the first function line separated by commas inside square brackets, e.g.

[s,t]=mysum(a,b)

% in case you were in the mood of having your algorithm do something funky, as, perhaps,

% The "sum"
s=a+b;
% The "alternative sum"
t=a*b;

% Rule #10. Debug while you are writing. Check every line, as you are writing it, on your own command line before copying it into your function body. Not by running the function, but by being very explict. Pretend you're inside the function. Now what? In my example, on the inside,

a=8;
b=9;
s=a+b;

% If that works, your algorithm works, at least when fed reasonable inputs. But here the input/output checking will start. Should you be able to feed it characters? Matrices? Cells? Should you adapt the algorithm based on the types of inputs, or issue warning and error messages? Anything you want.
%
%% A function only ever does one thing well
% Write the shortest possible functions that have the clearest path between input and output. Chances are, you will use it again. The next examples will make this clear.
%
%% In-class exercise 1
% Write a function that takes a certain time variable (the first input), a certain time series (the second input), and then a vector with amplitudes (the third input), a vector with periods (the fourth input), and a vector with phase offsets (the fifth input). On the inside, it produces a superposition of sine waves with those amplitudes, periods, and phase offsets, and calculates the correlation coefficient  (the first output) of the synthetic with the given data, and returns the synthetic as well (the second output). Something like this:

function [rsu,uoft]=myfourier(t,soft,A,P,PH)
% [rsu,uoft]=myfourier(t,soft,A,P,PH)
% 
% Produces a weighted superposition of sine waves evaluated at the independent 
% variable and calculates their correlation coefficient.
%
% INPUT:
%
% t        The independent variable, e.g. time in a unit
% soft     The dependent variable, e.g. a temperature as a function of time
% A        A vector with amplitudes, e.g. [1 2 3]
% P        A vector with periods, e.g. [0 12 24]
% PH       A vector with phase offsets, e.g. [6 pi/2 pi]
%
% OUTPUT:
%
% rsu      The correlation coefficient between soft (the input)... and
% uoft     The synthetic time series generate from the inputs

% TESTED ON: 9.1.0.441655 (R2016b)
% WRITTEN BY: fjsimons@princeton.edu, 03/15/2017

% And now it begins

% (While you make that - two lines of code if you can manage that!), I make a function that gets you a t and an soft that you can feed to your own new little code.
%
%% In-class exercise 2
% Write a function that takes the same first two inputs as in the previous exercise, i.e., a certain time variable (the first input) and a certain time series (the second input), and which computes a Hanning-windowed periodogram at an appropriate frequency axis, returning both as outputs. Call this function, something like this:

function [f,Pf]=mypdgram(t,soft)

%
%% In-class exercise 3
% Write a function that takes a certain time variable (the first input) and a certain time series (the second input), and then another time variable and another time series (the third and fourth inputs), and which makes a cross-plot of the first with respect to the second time series after checking that the two time variables were identical!
%
%
%% In-class exercise 4
% Adapt your function from the section above to deal with non-equal time variables, via interpolation to a common time axis

