Read more about this book |

*(For more resources on this subject, see here.)*

The reader will benefit from the previous article on GNU Octave Variables.

# Basic arithmetic

Octave offers easy ways to perform different arithmetic operations. This ranges from simple addition and multiplication to very complicated linear algebra. In this section, we will go through the most basic arithmetic operations, such as addition, subtraction, multiplication, and left and right division. In general, we should think of these operations in the framework of linear algebra and not in terms of arithmetic of simple scalars.

## Addition and subtraction

We begin with addition.

# Time for action – doing addition and subtraction operations

- I have lost track of the variables! Let us start afresh and clear all variables first:

octave:66> clear

(Check with

*whos*to see if we cleared everything). - Now, we define four variables in a single command line(!)

octave:67> a = 2; b=[1 2 3]; c=[1; 2; 3]; A=[1 2 3; 4 5 6];

Note that there is an important difference between the variables

*b*and*c*; namely,*b*is a row vector, whereas*c*is a column vector. - Let us jump into it and try to add the different variables. This is done using the
*+*character:

octave:68>a+a

ans = 4

octave:69>a+b

ans =

3 4 5

octave:70>b+b

ans =

2 4 6

octave:71>b+c

error: operator +: nonconformant arguments (op1 is 1x3, op2 is

3x1)

*It is often convenient to enter multiple commands on the same line. Try to test the difference in separating the commands with commas and semicolons.*

*What just happened?*

The output from Command 68 should be clear; we add the scalar a with itself. In Command 69, we see that the *+* operator simply adds the scalar a to each element in the *b* row vector. This is named element-wise addition. It also works if we add a scalar to a matrix or a higher dimensional array.

Now, if *+* is applied between two vectors, it will add the elements together element-wise if and only if the two vectors have the same size, that is, they have same number of rows or columns. This is also what we would expect from basic linear algebra.

From Command 70 and 71, we see that *b+b* is valid, but *b+c* is not, because b is a row vector and *c* is a column vector—they do not have the same size. In the last case, Octave produces an error message stating the problem. This would also be a problem if we tried to add, say *b* with *A*:

octave:72>b+A

error: operator +: nonconformant arguments (op1 is 1x3, op2 is 2x3)

From the above examples, we see that adding a scalar to a vector or a matrix is a special case. It is allowed even though the dimensions do not match! When adding and subtracting vectors and matrices, the sizes must be the same. Not surprisingly, subtraction is done using the - operator. The same rules apply here, for example:

octave:73> b-b

ans =

0 0 0

is fine, but:

octave:74> b-c

error: operator -: nonconformant arguments (op1 is 1x3, op2 is 2x3)

produces an error.

## Matrix multiplication

The * operator is used for matrix multiplication. Recall from linear algebra that we cannot multiply any two matrices. Furthermore, matrix multiplication is not commutative. For example, consider the two matrices:

The matrix product **AB** is defined, but **BA** is not. If **A** is size *n* x *k* and **B** has size *k* x *m*, the matrix product **AB** will be a matrix with size *n* x *m*. From this, we know that the number of columns of the "left" matrix must match the number of rows of the "right" matrix. We may think of this as (*n* x *k*)(*k* x *m*) = *n* x *m*. In the example above, the matrix product **AB** therefore results in a *2* x *3* matrix:

# Time for action – doing multiplication operations

Let us try to perform some of the same operations for multiplication as we did for addition:

octave:75> a*a

ans = 4

octave:76> a*b

ans =

2 4 6

octave:77> b*b

error: operator *: nonconformant arguments (op1 is 1x3, op2 is 1x3)

octave:78> b*c

ans = 14

*What just happened?*

From Command 75, we see that * multiplies two scalar variables just like standard multiplication. In agreement with linear algebra, we can also multiply a scalar by each element in a vector as shown by the output from Command 76. Command 77 produces an error—recall that *b* is a row vector which Octave also interprets as a *1* x *3* matrix, so we try to perform the matrix multiplication (*1* x *3*)(*1* x *3*), which is not valid. In Command 78, on the other hand, we have (*1* x *3*)(*3* x *1*) since c is a column vector yielding a matrix with size *1* x *1*, that is, a scalar. This is, of course, just the dot product between *b* and *c*.

Let us try an additional example and perform the matrix multiplication between **A** and **B** discussed above. First, we need to instantiate the two matrices, and then we multiply them:

octave:79> A=[1 2; 3 4]; B=[1 2 3; 4 5 6];

octave:80> A*B

ans =

9 12 15

19 26 33

octave:81> B*A

error: operator *: nonconformant arguments (op1 is 2x3, op2 is 2x2)

Seems like Octave knows linear algebra!

## Element-by-element, power, and transpose operations

If the sizes of two arrays are the same, Octave provides a convenient way to multiply the elements element-wise. For example, for **B**:

octave:82> B.*B

ans =

1 4 9

16 25 36

Notice that the period (full stop) character precedes the multiplication operator. The period character can also be used in connection with other operators. For example:

octave:83> B.+B

ans =

2 4 6

8 10 12

which is the same as the command *B+B*.

If we wish to raise each element in *B* to the power 2.1, we use the element-wise power operator.ˆ:

octave:84> B.^2.1

ans =

1.0000 4.2871 10.0451

18.3792 29.3655 43.0643

You can perform element-wise power operation on two matrices as well (if they are of the same size, of course):

octave:85> B.^B

ans =

1 4 27

256 3125 46656

*If the power is a real number, you can use ˆ instead of .ˆ; that is, instead of Command 84 above, you can use:octave:84>Bˆ2.1*

Transposing a vector or matrix is done via the 'operator. To transpose B, we simply type:

octave:86> B'

ans =

1 4

2 5

3 6

Strictly, the ' operator is a complex conjugate transpose operator. We can see this in the following examples:

octave:87> B = [1 2; 3 4] + I.*eye(2)

B =

1 + 1i 2 + 0i

3 + 0i 4 + 1i

octave:88> B'

ans =

1 - 1i 3 - 0i

2 - 0i 4 - 1i

Note that in Command 87, we have used the .* operator to multiply the imaginary unit with all the elements in the diagonal matrix produced by *eye(2)*. Finally, note that the command transpose(B)or the operator .' will transpose the matrix, but not complex conjugate the elements.

Read more about this book |

*(For more resources on this subject, see here.)*

## Operators for structures and cell arrays

Arithmetic on structure fields and cells array elements is straightforward. First, let us see an example of a structure field operation:

octave:89> s = struct("A", [1 2; 3 4], "x", [1; 2]);

octave:90>s.A*s.x

ans =

5

11

and the equivalent cell array operation:

octave:91> c = {[1 2; 3 4], [1;2]};

octave:92> c{1}*c{2}

ans =

5

11

Arithmetic operations on entire structures and cell arrays are not defined in Octave.

## Solving linear equation systems: left and right division

You may have wondered why division was not included above. We know what it means to divide two scalars, but it makes no sense to talk about division in the context of linear algebra. Nevertheless, Octave defines two different operators, namely, right and left division, which need to be explained in some detail. It is probably easiest to discuss this via a specific example. Consider a system of linear equations (Equation (2.6)):

We can write this in matrix notation as, Equation (2.7):

where:

If the coefficient matrix **A** is invertible (in fact it is), we can solve this linear equation system by multiplying both sides of Equation (2.7) with the inverse of **A**, denoted **A**^{-1}:

In Octave, the command *A\y* is equivalent to **A**^{-1}**y**. Notice the backslash. This is named left division, and you can probably guess why.

The right division (forward slash) command, *A/y*, is equivalent to **yA**^{-1}, which is of course not defined in this case because the vector **y** has size *3* x *1* and **A** has size *3* x *3*; that is, the matrix product cannot be carried out.

# Time for action – doing left and right division

- We need to instantiate the coefficient matrix
**A**and vector**y**first:octave:93> A=[2 1 -3; 4 -2 -2; -1 0.5 -0.5]; y = [1; 3; 1.5];

- The solution to the linear equation system, Equation (2.6), is then found directly via the command:
octave:94> A\y

ans =

-1.6250

-2.5000

-2.2500Easy!

*What just happened?*

It should be clear what happened. In Command 93, we instantiated the matrix *A* and the vector *y* that define the linear equation system in Equation (2.6). We then solve this system using the left division operator.

Let us try the right division operator, even though we know that it will cause problems:

octave:95> A/y

error: operator /: nonconformant arguments (op1 is 3x3, op2 is 3x1)

We see the expected error message. The right division operator will, however, work in the following command:

octave:96> A/A

ans =

1.0000 -0.0000 -0.0000

0.0000 1.0000 -0.0000

0.0000 0.0000 1.0000

This is the *3* x *3* identity matrix **I**. This result is easily understood because *A/A* is equivalent to **AA**^{-1}. Notice that due to numerical round-off errors and finite precision, the elements in this matrix are not exactly 1 on the diagonal and not exactly 0 for the off-diagonal elements, and Octave therefore displays the elements in floating point format.

What is the result for the command *A\A*? Try it out to check your answer.

The definitions of the left and right division operators also apply for scalar variables. Recall that the variable *a* has the value 2:

octave:97> 1/a

ans = 0.5000

This is just the fraction 1/2 with a in the denominator. Now, the left division operator:

octave:98> 1\a

ans = 2

which is equivalent to the fraction 2/1; that is, a is in the nominator. We can say that *a\1* is equivalent to *1/a*.

Above we learned that the .operator can be used in connection with other operators. This is also true for the left and right division operators:

octave:99> a./A

ans =

1.0000 2.0000 -0.6667

0.5000 -1.0000 -1.0000

-2.0000 4.0000 -4.0000

octave:100> a.\A

ans =

1.0000 0.5000 -1.5000

2.0000 -1.0000 -1.0000

-0.5000 0.2500 -0.2500

It is very important to stress that when performing element-wise left and right division with a scalar, you must use the .operator. This is different from addition, subtraction, and multiplication.

For element-wise matrix division, we can use:

octave:101> A./A

ans =

1 1 1

1 1 1

1 1 1

## Basic arithmetic for complex variables

It is also possible to perform arithmetic operations on complex variables. In fact, we can regard the operations above for real numbers as special cases of more general operations for complex variables.

When adding two complex numbers, we add the real parts and imaginary parts. In Octave, we simply use the + operator:

octave:102> z = 1 + 2I; w = 2 -3I;

octave:103> z + w

ans = 3 – 1i

The same goes for subtraction:

octave:104> z – w

ans = -1 + 5i

Multiplication of *z* and *w* is simply:

Let us see if Octave agrees:

octave105:> z*w

ans = 8 + 1i

Now, you may recall that when dividing two complex numbers, you multiply the nominator and denominator with the complex conjugate of the denominator. In the case of *z/w*, we get:

To perform this division in Octave, we can simply use the left or right division operator:

octave:106> z/w

ans = -0.30769 + 0.53846i

octave:107> w\z

ans = -0.30769 + 0.53846i

just as we did for real numbers.

You can also perform addition, subtraction, and multiplication with complex vectors and matrices. You can even solve complex linear equation systems with the left division operator like it was done above for a real equation system.

## Summary of arithmetic operators

Let us summarize the operators we have discussed above:

Read more about this book |

*(For more resources on this subject, see here.)*

# Comparison operators and precedence rules

In the previous section, we discussed the basic arithmetic operations. In this section, we will learn how to compare different variables. Octave (like many other programming languages) uses very intuitive operator characters for this. They are:

For Octave's comparison operators, true is equivalent to a non-zero value and false is equivalent to 0. Let us see a few examples—recall the matrix *A* from Command 93:

octave:108> A(2,1) == 1

ans = 1

octave:109>A(2,1) == 2

ans = 0

octave:110> A(2,1) > 0

ans = 1

octave:111> A(2,1) != 4

ans = 1

Instead of using != for "not equal to", you can use ˜=.

You may be familiar with these operators from another programming language. However, in Octave you can compare vectors and matrices. To compare the first column in *A* with another column vector, we use:

octave:112> A(:,1) >= [2; 2; 0]

ans =

1

1

0

Octave:113> A > ones(3,3)

ans =

1 0 0

1 0 0

0 0 0

that is, the comparison is performed element-wise. This, of course, means that the array dimensions must match except if one of the variables is a scalar.

You can also compare characters using the comparison operators above. However, they cannot be used to compare entire strings. For example:

octave:114> "a"=="a"

ans = 1

compare the character *a* with *a*, and:

octave:115> "hello"=="henno"

ans = 1 1 0 0 1

compare all character elements in the string *hello* with the characters in *henno* (elementwise). However, the command *"hello"=="helloo"* is not valid, because the two strings do not have the same dimensions. If you wish to compare the two strings, use *strcmp* (which is an abbreviation for string compare):

octave:116>strcmp("hello", "helloo")

ans = 0

meaning false, because the two strings are not the same.

As mentioned above, the result of a comparison operation is either true (value 1) or false (value 0). In computer science, we refer to this as a Boolean type, after the English mathematician George Boole. Note that because Octave is a vectorized programming language, the resulting Boolean can be an array with elements that are both true and false.

*Octave interprets all non-zero values as true.*

## Precedence rules

You can do many operations in a single command line, and it is important to know how such a command is interpreted in Octave.

# Time for action – working with precedence rules

- Let us see an example:
octave:117> A*y + a

ans =

2.5000

-3.0000

1.7500Here, Octave first performs the matrix multiplication between

*A*and*y*, and then adds a to that result. We say that multiplication has higher precedence than addition. - Let us try two other examples:
octave:118> A*y.^2

ans =

4.2500

-18.5000

2.3750

octave:119> (A*y).^2

ans =

0.2500

25.0000

0.0625

*What just happened?*

In command 118, because the .ˆ operator has higher precedence than *, Octave first calculates element-wise power operation y.ˆ2, and then performs the matrix multiplication. In command 190, by applying parenthesis, we can perform the matrix multiplication first, and then do the power operation on the resulting vector.

*The precedence rules are given below for the operators that we have discussed in this article:*

*When in doubt, you should always use parenthesis to ensure that Octave performs the computations in the order that you want.*

# A few hints

Instead of using the left division operator to solve a linear equation system, you can do it "by hand". Let us try this using the equation system given by Equation (2.6) with the solution given in Equation (2.9). First we need to calculate the inverse of *A* (which exists). This is done via the *inv* function:

octave:120>inverse_A = inv(A)

inverse_A =

0.2500 -0.1250 -1.0000

0.5000 -0.5000 -1.0000

0.0000 -0.2500 -1.0000

We can now simply perform the matrix multiplication **A**^{-1}**y** to get the solution:

octave:121>inverse_A*y

ans =

-1.6250

-2.5000

-2.2500

This output is similar to the output from Command 94. Now, when Octave performs the left division operation, it does not first invert *A* and then multiply that result with *y*. Octave has many different algorithms it can use for this operation, depending on the specific nature of the matrix. The results from these algorithms are usually more precise and much quicker than performing the individual steps. In this particular example, it does not really make a big difference, because the problem is so simple.

*In general, do not break your calculations up into individual steps if Octave already has an in-built operator or functionality that does the same in one single step. It is highly likely that the single operation is faster and more precise.*

If we replace the coefficient matrix **A** in Equation (2.8) with the following matrix:

and try to solve the corresponding linear equation system, Octave will display a warning message:

octave:122:> A=[2 1 -3; 4 -2 -2; -2 1 1]; A\y

warning: dgelsd : rank deficient 3x3 matrix, rank = 2

ans =

0.3000

-0.1250

-0.1750

The result in this case is the minimum norm solution to the improperly defined equation system, which we will not discuss here. What is important is the warning message because this tells us that the matrix does not have full rank, that is, the rows (or columns) in the matrix are not linearly independent. This in turn means that no unique solution to the linear equation system exists. If you inspect the matrix, you will quickly see that the third row is just the second row multiplied with minus one half, so these two rows are linearly dependent. You can check the rank of a matrix by:

octave:123> rank(A)

ans = 2

This calculation is already done for you in Command 122, and shows up in the warning message. You should, of course, always perform this check if you are not absolutely sure about the rank of a matrix.

# Summary

We went through a lot of the basics in this and the previous article. Specifically, we learned:

- How to instantiate scalar, vector, and matrix variables.
- How to instantiate complex variables.
- How to instantiate a text string.
- How to access and change the values of array elements.
- About structures, cell arrays, and multidimensional arrays.
- How to retrieve important information about the variables.
- How to add and subtract vectors and matrices.
- About matrix multiplication.
- Solving linear equation systems.
- How to compare scalars, vectors, and matrices.
- Some additional helpful functionality.
- Precedence rules.

**Further resources on this subject:**

- Interacting with GNU Octave: Variables [Article]
- What Can You Do with Sage Math? [Article]
- Sage: Tips and Tricks [Article]
- Creating a Reporting Site using BIRT [Article]
- Organizing, Clarifying and Communicating the R Data Analysis [Article]