# Octave / MATLAB basics

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
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
>>
```

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¶

```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);

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¶

```>> 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.