===== V - Octave tutorial ===== ==== 5.1 - Basic operations ==== * We can type regular operations in octave like +, -, *, /, ^. * The comment in Octave is represented by the percentage symbol: '%' * We can evaluate boolean conditions with '==' and '~=' or '&&' or '||' or the function xor(a,b). * To change the Octave prompt, we can use the command: PS1('>> '); * We can assign variable with: a = 3; * Note that the ';' at the end of a statement supresses the output once enter is pressed. * We can assign a string with: b = 'hi'; * The value of \(\pi\) can be used with: a = pi; * For complex display, we can use the 'disp(val)' command. * We can also display string with for instance:disp(sprintf('2 decimanls: %0.2f', a)) * To display numbers with high precision, we can enter the command format long * To display numbers with lw precision, we can enter the command format short * We can generate a matrix with: A = [ 1 2; 3 4; 5 6]. This will generate a 3x2 matrix. * We can generate a vector with: v = [1; 2; 3] * We can also build a range with **v = 1:0.1:2** : this will start from 1, increment each step by 0.1, until we reach 2.0. * If we want to use a step of 1, we can just write: **v = 1:6** instead. * To generate a matrix with only "1" values everywhere we can use: ** C = ones(2,3)** (\(C \in \mathbb{R}^{2 \times 3}\)). * Similarly we can use the method **zeros(n,m)** to generate a matrix full of zeros. * Also the **rand(n,m)** will generate a random nxm matrix with value from the uniform distribution [0,1). * Same with **randn(n,m)** which will generate a random matrix this time taking values from the standard gaussian distribution (mean=0 and \(\sigma=1\)). * We can display an histogram for instance with:w = -6 +sqrt(10)*(randn(1,10000)) hist(w,50) * To build an identity matrix we can use the **eye(n)** command. * To get some help on a given command we can use **help cmdname** ==== 5.2 - Moving Data Around ==== * The command **size(A)** will return the size of a matrix A. Note that the result of this call is a 1x2 matrix. * We can use **size(A,1)** to retrieve only the number of rows from A, or **size(A,2)** to retrieve the number of columns. * If we have a vector **v**, the command **length(v)** will give us the size of the longer dimension of v, so the actual number of components of the vector. (Note that this also work for matrices, but less usefull in that case). * We can get the current working directory with the command **pwd**. * We can use the commands **cd**, and **ls** * To load a file we use the **load** command. * When passing a single string argument to load, we can ommit the parenthesis and the quotation marks. (Is this a general rule ?), Such that the following calls are equivalent:load featuresX.dat load('featuresX.dat') * When loading data this way, Octave will create the corresponding variables with the names 'featuresX' and 'priceY'. * In Octave we use single quotes to represent strings. * The command **who** shows us the list of variables available in our current workspace. * The **whos** command provides additional details on the vars. * To remove a variable we can use the command **clear featuresX**. To clear all variables, we just type **clear**. * To take an a sub part of a vector we can use for instance: **v = priceY(1:10)** * To save a variable we can do: **save hello.mat v;** : this will save the variable v to the file hello.mat, in binary compressed format. * To save in a text format we do: **save hello.txt v -ascii**. * To access the element on row i and col j of a matrix A, we can use **A(i,j)**. * To retrieve a complete row i from a matrix A we call **A(i,:)**. ':' means every element along that row/column. Similarly we can use **A(:,j)** to get everything on the column j. * Note that we can also use an array as one of the parameter i or j mentioned above, so: **A([1 3],:)** will return the matrix built from the first and the third rows of A. * We can also use the previously described access notation to perform assignment, like for instance:A(:,2) = [10; 11; 12] % assuming A is 3xn here * To append a column vector to a matrix A we can do:A = [A, [100; 101; 102]]; % Append to the right. * We can put all the elements of a matrix A in a column vector with: **v = A(:)**. * If we have \(A \in R^{m \times n_1}\) and \(B \in R^{m \times n_2}\), we can do : **C = [A B]** to concatenate the matrices and get \(C \in R^{m \times (n_1+n_2)}\). Similarly we can use **C = [A; B]** to put the matrix B under A. Also note that **[A B]** is the same thing as **[A, B]**. ==== 5.3 - Computing on Data ==== * For matrices, we can do element wise operations with for instance the operator **.*** or **.^**. We can even do something like: **1 ./ A**. * We can also apply functions to the matrices: log(A), exp(A), abs(A), -A, floor(A), ceil(A) * To increment the values of a vector by 1, we can do: v + ones(length(v),1) * We can also add scalars to vectors: **v + 1**. * To compute the transpose of a matrix we type: **A'** * We can retrieve max/min values from vectors and matrices with **max(v)**, **min(v)**. * For a vector: **[val, ind] = max(v)** => will retrieve the max value of v in **val**, and its index in the vector in **ind**. * For a matrix, **max(A)** will return the max for **each column** of the matrix (it does the same thing as max(A,[],1), whereas max(A,[],2) will return the max per row). * To simply get the max of a matrix A, we can do : **max(max(A))** or **max(A(:))**. * We can also do element wise comparaison: **v < 3**. We can also do **find(v < 3)** to retrieve the indices of the vector v where the values are less than 3 in that case. find is also working for matrices (check the help !): **[r,c] = find(A >= 7)**. * We can generate the magic matrices with **A = magic(3)** (not actually usefull for machine learning). * For a vector we can use the sum function: **sum(v)**, for a matrix, we use sum(A,1) to su per column, or sum(A,2) to sum per row. * For a vector we can use the prod function to multiply all the elements together: **prod(v)**. * We can use **flipud(A)** to mirror a matrix horizontally. * To inverted a matrix we use **pinv(A)**. ==== 5.4 - Plotting Data ==== * Let's consider the vector: **t=[0:0.01:0.98]** * Then we can build: **y1=sin(2*pi*4*t)** * To plot, this function: **plot(t,y1)** * Then we continue with the code:y2=cos(2*i*4*t); plot(t,y2); % This will replace the previous drawing of y1 in the octave figure. % Now to draw both curves: plot(t,y1); hold on; % Tell octave to keep the previous drawing and draw on top of it. plot(t,y2,'r'); % This curve will be in red. xlabel('time') % Set the horizontal axis label. ylabel('value') % Set the vertical axis label. legend('sin','cos') % Add legend for the curves. title('My plot') % Set the title of this figure. cd /cygdrive/w/Temp print -dpng 'myPlot.png' % Save the current figure in a file. close % remove the figure. figure(1); plot(t,y1); % Draw on figure 1 figure(2); plot(t,y2); % Draw on figure 2 subplot(1,2,1); %Divides the plot area in a 1x2 grid and access the first element. plot(t,y1); subplot(1,2,2); plot(t,y2); axis([0.5 1 -1 1]); % Set the range for the axis of the figure. clf; % clear the figure. % trick to display a matrix: A = magic(5) imagesc(A); % Will display the matrix on the figure with multiple colors. imagesc(A), colorbar, colormap gray; % more complex display. * Note that we use the **comma** to chain calls in Octave. ==== 5.5 - Control Statements: for, while, if statements ==== * To write a for loop we use: v=zeros(10,1) for i=1:10, v(i) = 2^i; end; * Octave also supports **break** and **continue** in for loops. * To build a while loop:i = 1; while i <= 5, v(i) = 100; i = i+1; end; * With an if statement:i=1; while true, v(i) = 999; i = i+1; if i == 6, break; end; end; * For a complete if structure:if v(1)==1, disp('The value is one'); elseif v(1) == 2, disp('The value is two'); else disp('The value is something else'); end * To exit octave, we can type **exit** or **quit** === defining functions === * Functions are defined in files with the extension **.m**. * Such a file should contain for instance:function y = squareThisNumber(x) y = x^2; * We can modify the octave search path with :**addpath('/cygdrive/w/Temp')**. * We can also return multiple results:function [y1, y2] = squareAndCubeThisNumber(x) y1 = x^2; y2 = x^3; ==== 5.6 - Vectorization ==== * Use vector and matrix computation when possible ! => more efficient and more simple. * For gradien descent for instance we can use the vectorized update rule: \[ \theta := \theta - \alpha \frac{1}{m} \sum\limits_{i=1}^m (h_\theta(x^{(i)}) - y^{(i)}) x^{(i)} \] ==== 5.7 - Working on and submitting programming exercises ====