Quick intro to the $\texttt{sort}$ function.

In [1]:
x = randi(10, 1, 10)
[x_sorted, idx_order] = sort(x)
x(idx_order)

[x_sorted_descend, ~] = sort(x, 'descend')
x =

    4    7    1   10    1    7    6    3    6   10

x_sorted =

    1    1    3    4    6    6    7    7   10   10

idx_order =

    3    5    8    1    7    9    2    6    4   10

ans =

    1    1    3    4    6    6    7    7   10   10

x_sorted_descend =

   10   10    7    7    6    6    4    3    1    1

Code Profiling

In [2]:
profile on
M = magic(100);
profile off
info = profile('info')
profile clear
info =

  scalar structure containing the fields:

    FunctionTable =

      23x1 struct array containing the fields:

        FunctionName
        TotalTime
        NumCalls
        IsRecursive
        Parents
        Children

    Hierarchical =

      2x1 struct array containing the fields:

        Index
        SelfTime
        TotalTime
        NumCalls
        Children


In [3]:
info.FunctionTable.FunctionName
ans = magic
ans = nargin
ans = binary !=
ans = fix
ans = binary <
ans = mod
ans = binary ==
ans = binary *
ans = reshape
ans = postfix '
ans = fliplr
ans = flip
ans = binary >
ans = ndims
ans = size
ans = isscalar
ans = isindex
ans = prefix !
ans = max
ans = prefix -
ans = profile
ans = false
ans = __profiler_enable__
In [4]:
% convert total time to an array with square brackets
TotalTime = [info.FunctionTable.TotalTime]

% sort in the descending order, most total time first
[TT_sorted, idx] = sort(TotalTime, 'descend');
idx

% convert FunctionNames to a cell array with curly braces
Names = {info.FunctionTable.FunctionName};
Names = Names(idx) % reorder a cell array with parentheses, access elements with curly braces
TotalTime =

 Columns 1 through 6:

   0.00097609   0.00001860   0.00001192   0.00000095   0.00000405   0.00000691

 Columns 7 through 12:

   0.00000095   0.00000000   0.00053906   0.00005507   0.00097156   0.00036550

 Columns 13 through 18:

   0.00000095   0.00000310   0.00000906   0.00000310   0.00000906   0.00000310

 Columns 19 through 23:

   0.00002313   0.00000215   0.00010490   0.00000501   0.00000000

idx =

 Columns 1 through 16:

    1   11    9   12   21   10   19    2    3   15   17    6   22    5   14   16

 Columns 17 through 23:

   18   20    4    7   13    8   23

Names =
{
  [1,1] = magic
  [1,2] = fliplr
  [1,3] = reshape
  [1,4] = flip
  [1,5] = profile
  [1,6] = postfix '
  [1,7] = max
  [1,8] = nargin
  [1,9] = binary !=
  [1,10] = size
  [1,11] = isindex
  [1,12] = mod
  [1,13] = false
  [1,14] = binary <
  [1,15] = ndims
  [1,16] = isscalar
  [1,17] = prefix !
  [1,18] = prefix -
  [1,19] = fix
  [1,20] = binary ==
  [1,21] = binary >
  [1,22] = binary *
  [1,23] = __profiler_enable__
}

Profiling your own functions

In [5]:
function x = solveAb(A, b)                                                      
  % solves the system of equations (matrix equation)                            
  % A x = b                                                                     
  % where A, b are known and x is unknown                                       
                                                                                   
  Ainv = pinv(A);                                                                  
  x = Ainv * b;                                                                    
end
In [6]:
N = 1e3;
A = rand(N, N);
b = rand(N, 1);
profile on
x = solveAb(A, b);
profile off
info = profile('info');
profile clear

% check how well we do, should give close to 0 if A x = b
sum(abs(A * x - b))

tt = [info.FunctionTable.TotalTime];
[tt_sorted, idx] = sort(tt, 'descend');
tt_sorted
Names = {info.FunctionTable.FunctionName};
Names(idx)
ans =  0.00000000028334
tt_sorted =

   2.99948   0.00031   0.00005   0.00004   0.00001   0.00000   0.00000   0.00000

ans =
{
  [1,1] = pinv
  [1,2] = binary *
  [1,3] = profile
  [1,4] = solveAb
  [1,5] = binary !=
  [1,6] = false
  [1,7] = nargin
  [1,8] = __profiler_enable__
}

Error Handling

Throwing errors

Errors break execution, so use them when program should not continue.

In [18]:
error('This is an erorr');
error: This is an erorr
In [19]:
function change_third_element(a)
     if length(a) < 3
        error('Argument is not long enough');
     end
     a(3) = -1;
end
In [20]:
change_third_element([1, 2, 3])
In [21]:
change_third_element([1, 2])
error: Argument is not long enough
error: called from
    change_third_element at line 3 column 9
In [11]:
A = rand(4, 4);
x = rand(3, 1);

% in-built functions also produce errors
A * x
error: operator *: nonconformant arguments (op1 is 4x4, op2 is 3x1)

Using warnings

Errors are used more often.

In [12]:
function x = add2_to_third_el(x)
    if length(x) < 3
        warning('Argument is not long enough, returning unchanged');
    else
        x(3) = x(3) + 2;
    end
end
In [13]:
add2_to_third_el([1, 2, 3])
ans =

   1   2   5

In [14]:
add2_to_third_el([1, 2])
warning: Argument is not long enough, returning unchanged
warning: called from
    add2_to_third_el at line 3 column 9
ans =

   1   2

In [15]:
A = [rand(3, 3), zeros(3, 1); zeros(1, 4)]
inv(A)
A =

   0.44169   0.18619   0.17367   0.00000
   0.15728   0.34540   0.57431   0.00000
   0.66393   0.45272   0.41852   0.00000
   0.00000   0.00000   0.00000   0.00000

warning: matrix singular to machine precision
ans =

   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf

Disabling warnings.

In [16]:
warning('off');
A = [rand(3, 3), zeros(3, 1); zeros(1, 4)];
inv(A)
ans =

   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf

In [22]:
warning('on');
A = [rand(3, 3), zeros(3, 1); zeros(1, 4)];
inv(A)
warning: matrix singular to machine precision
ans =

   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf