Octave / MATLAB - lops, conditional processing, functions
Octave is an open source scientific computing package. It has a GUI, kernel and a programming language modeled after MATLAB. File extensions are .m
. This page is a guide to the octave programming language.
General caveats
- You end statements with a
;
. If not, the kernel does not throw an error, instead will echo the output of each line. - If you do not catch the output of an operation in a variable, a default variable called
ans
is created and that holds the value. At any time,ans
holds value of latest operation. - Matlab / octave functions can return multiple values.
Variables
Variables can be assigned without initializing.
a = 1;
b = [1,2,4]; % row vector
% Use % for comments
c = [5;6;7]; % col vector
2D arrays can be initialized as
>> a2d = [1,2,3;4,5,6;7,8,9] % ';' is used to separate rows.
a2d =
1 2 3
4 5 6
7 8 9
Standard matrix creation functions
>> eye(3) % identity
ans =
Diagonal Matrix
1 0 0
0 1 0
0 0 1
>> zeros(2,3)
ans =
0 0 0
0 0 0
>> rand(2,5) % uniform random numbers between 1,1
ans =
0.86289 0.18309 0.48379 0.36600 0.63669
0.32459 0.89961 0.79682 0.39961 0.15351
>> randn(3,4)
ans =
1.151159 0.022623 -1.030988 0.460505
-0.386885 -0.188437 0.339421 -1.131755
0.573182 0.451552 -0.307362 -1.717639
>> magic(3) % creates matrix whose each row, col, diagonal sum to same value
ans =
8 1 6
3 5 7
4 9 2
Automatic map
operations
Octave is designed to work primarily with arrays and vectors. Thus when you pass an array or vector to a standard function or operator, it automatically maps the function on each element and runs it and returns either an array/vector or scalar, depending on the operation.
>> squares = [4,9,16,25,36,49];
>> sqrt(squares) % returns a vector output
ans = 2 3 4 5 6 7
>> min(squares)
ans = 4 % scalar output
When you run functions on a 2D matrix, they run on each column vector:
>> sum(magic(3)) % default is columnwise operation
ans =
15 15 15
>> sum(magic(3), 2) % does a row-wise operation
ans =
15
15
15
>> prod(magic(3)) % multiply each element in the matrix. Here multiplies each in col vector
ans =
96 45 84
>> max(magic(3))
ans =
8 9 7
Functions in Octave can return multiple values. For instance:
>> [val, index] = min(squares)
val = 4
index = 1
>>
Automatic broadcasting
When you operate a scalar against a vector, matlab will automatically scale up that scalar into a vector and perform an element wise computation as shown below:
>> x=-2:0.7:2
x = -2.0000 -1.3000 -0.6000 0.1000 0.8000 1.5000
>> x+10
ans = 8.0000 8.7000 9.4000 10.1000 10.8000 11.5000
>>
Similarly when you multiply, subtract or divide a scalar from a vector, it is automatically broadcasted.
Looping through a matrix
The automatic map operations should have most things covered for you. Still, you might need to write a loop. Below is syntax of for
loop.
for iterator=<range>,
operation1;
operation2;
condition check
operation3;
break;
condition check2
operation4;
continue;
end;
Note the ,
at end of the line with for
.
>> indices=1:10;
>> for i=indices,
disp(i);
end;
1
2
3
.
.
.
While loop
The syntax for while loop is
while condition,
operation;
end;
Once again, note the ,
at line 1.
Array multiplication
There are two types of multiplication
- element wise - which is accomplished by prefixing the operator with .
such as: .<operator>
or .*
- matrix multiplication - which will happen when you use *
.
Thus:
>> x
x = -2.0000 -1.3000 -0.6000 0.1000 0.8000 1.5000
>> x2 = [1,2,3,4,5,6]
x2 = 1 2 3 4 5 6
>> x.*x2
ans = -2.00000 -2.60000 -1.80000 0.40000 4.00000 9.00000
>>
When you want to multiply two matrixes, you do:
>> x*transpose(x2)
ans = 7.0000
Transposing a matrix
You can call the built-in transpose()
function (shown previously) or use the '
operator.
>> x2'
ans =
1
2
3
4
5
6
Reshaping matrixes
You can reshape using the reshape(<arr>, nrows, ncols)
function. Note, it flows elements column wise, followed by rows as shown below:
>> vec = 1:16;
>> reshape(vec, 2,8)
ans =
1 3 5 7 9 11 13 15
2 4 6 8 10 12 14 16
>> reshape(vec, 4,4) % note how elements flow along columns, not rows.
ans =
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
Range functions
You can generate uniformly spaced vectors, using 2 methods. If you want uniformly spaced vectors, use the :
operator. If you want a specific number of elements within a range, then use the linspace
function.
The :
operator takes syntax start:spacing:end
first_10_even_numbers = 0:2:21
first_10_even_numbers = 0 2 4 6 8 10 12 14 16 18 20
The linspace
function takes arguments linspace(start, end, numPoints)
where start and end are included.
>> linspace(1,10,7)
ans = 1.0000 2.5000 4.0000 5.5000 7.0000 8.5000 10.0000
Conditional processing
Logical operators in octave are <, >, <=, >=, ~, ==, ~=, &, |
. Matlab returns 1
for True and 0
for False. Thus
>> heat = 74
heat = 74
>> heat < 100
ans = 1
>> heat > 100
ans = 0
>> heat == 74
ans = 1
Conditional operators also map
on all elements of the vector. Thus to find elements in a vector greater than a threshold, do:
>> v1 = linspace(1,10,7);
>> ind = v1 > 5 % returns truth vector
ind = 0 0 0 1 1 1 1
>> vals = v1(ind) % use truth vector as index
vals = 5.5000 7.0000 8.5000 10.0000
To find values that fall between a range:
>> v1(v1<8 & v1>3)
ans = 4.0000 5.5000 7.0000
if-elseif-else
blocks
Jump to defining functions if you want to read that first.
function charge = parkingRates(hours)
%Calculates parking charge based on number of hours%
if hours <=1
charge = 2;
elseif hours<=8 && hours>1
charge = hours*0.75;
else
charge = 9;
end
end
The &&
operator is a performance opt that Matlab editor suggested. Else I would use only one of it.
Styling print outputs
Use disp
to display. You can style print outputs with sprintf
and sending the string composed to disp()
.
>> vec1 = [2,3,4,5];
>> disp(vec1)
2 3 4 5
>> disp(sprintf("Mean of the array is %0.3f", mean(vec1)))
Mean of the array is 3.500
Use C
style statements within sprintf
.
Array indexing, slicing, dicing
Consider this 4x4
matrix:
>> readings=linspace(1,10,16);
>> readings = reshape(readings, 4,4)
readings =
1.0000 3.4000 5.8000 8.2000
1.6000 4.0000 6.4000 8.8000
2.2000 4.6000 7.0000 9.4000
2.8000 5.2000 7.6000 10.0000
>>
To get the first column vector, use :,n
where :
means all rows here and replace n
with column number, starting with 1
instead of 0
.:
>> readings(:,1) % Note: matlab is 1 indexed, not 0 indexed
ans =
1.0000
1.6000
2.2000
2.8000
>>
Also note, I am using ()
to index arrays, not []
as in Python and other languages.
To dice the array by pulling 2nd, 3rd rows, 2nd, 3rd columns, do the following:
>> readings([2,3], [2,3])
ans =
4.0000 6.4000
4.6000 7.0000
Array concatenation
You can concatenate along rows or columns using the ,
or ;
operators:
>> [eye(3), randn(3)] % use , to concatenate along columns
ans =
1.00000 0.00000 0.00000 0.68098 -1.07370 -1.99950
0.00000 1.00000 0.00000 0.19421 0.06390 0.29864
0.00000 0.00000 1.00000 -0.03696 -0.24735 -0.18180
>> [eye(3); randn(3)] % use ; to concatenate along rows
ans =
1.00000 0.00000 0.00000
0.00000 1.00000 0.00000
0.00000 0.00000 1.00000
0.78756 -0.22399 0.59963
-0.93718 0.34779 0.27082
-2.00364 -0.45362 -1.47926
>>
Statistical operations on arrays
Let us start with an array as below:
>> vec45 = reshape(linspace(1,10,20), 4,5)
vec45 =
1.0000 2.8947 4.7895 6.6842 8.5789
1.4737 3.3684 5.2632 7.1579 9.0526
1.9474 3.8421 5.7368 7.6316 9.5263
2.4211 4.3158 6.2105 8.1053 10.0000
>>
Find mean of each column
>> mean(vec45)
ans = 1.7105 3.6053 5.5000 7.3947 9.2895
Find mean of each row
>> mean(vec45,2) % pass the dimension arg. Set it to 2 for mean along rows
ans =
4.7895
5.2632
5.7368
6.2105
Another way of doing this is to transpose the matrix and take regular mean.
Find mean of entire matrix Turn the matrix into a column vector and pass that to the mean.
>> mean(vec45(:))
ans = 5.5000
Writing functions
You call functions as
y = func_name(arg1, arg2);
The syntax to write functions is:
function [out1, out2...] = functionName(in1, in2, ...)
%Doc string%
statement1;
statement2;
out1 = statement;
out2 = statement;
...
end
There is no return
statement. All variables you define in the out parameter array (or scalar) will get returned. Matlab allows you to return more than one variable.
function result = hmean(vec1)
%calculates harmonic mean of the given vector%
vec1 = vec1(:)'; %convert to vectors
reciprocals = 1./vec1; %convert to reciprocals
sum_reciprocals = sum(reciprocals); % sum of reciprocals - the denominator
result = size(vec1)(2) / sum_reciprocals;
endfunction
>> hmean([2,3,4,5])
ans = 3.1169
>>
Reusing functions
A quick and easy way to reuse functions in other scripts is to put just the function (not anything else) in a separate .m
file with the same name as the function. Matlab will automatically search for it and import it.
To hack the search path, use addpath('full_path')
to add a folder to Octave path. This way, you can load a function or module from a different directory.