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 3×2 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 1×2 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:<code>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