GNU Octave method to operate on each item in a matrix. octave "arrayfun(...)" example

In GNU Octave version 3.4.3, I am having trouble applying a custom function to operate on each item/element in a matrix.

I have a (2,3) matrix that looks like:

mymatrix = [1,2,3;4,5,6];

mymatrix

   1   2   3
   4   5   6

I want to use each element of the matrix as an input, and run a custom function against it, and have the output of the function replace the content of mymatrix item by item.


Solution 1:

arrayfun works well for this:

arrayfun(@(x) 1/(1+e^(-x)), [0, 1; 2, 3])

Output:

ans =

   0.50000   0.73106
   0.88080   0.95257

This basically runs function 1/(1+e^(-x)) on each element of the matrix/vector.

Solution 2:

Alternatively you can use the element-wise operators like the following (note the dot prefix):

  • .+
  • .-
  • ./
  • e.^

For example

mymatrix = 1 ./ (1 .+ e.^(-mymatrix));

Solution 3:

Put this code in filename called "myfun.m"

function [ out ] = myfun(num)
  out = num + 5;
end

Put this code in filename called "main.m"

arrayfun(@myfun, [1, 0, -1; 3, 4, 5] )

Output:

ans =
   6   5   4
   8   9   10

Notice how the procedure (add 5) was applied to each item in the matrix.

PROTIP: Why this code on a sufficiently large matrix won't max out your quad-core CPU.

Below is an analysis of the arrayfun's capabilities from the perspective of Vectorization down through lowlevel C. Down straight to multi-core and multi-thread optimization on the bare metal:

This arrayfun code is "vectorized", and GNU Octave packages this code to be handed to pre-optimized C code rather than having GNU Octave manage its own glacial iteration. Operations performed in a vectorized way like this above are between 2 and 5 orders of magnitude faster than if you put this in a for loop. Vectorized code like this is usually good-enough for typical tasks, but if extracting every rev of horsepower from your Alienware's QUAD-CHIP 32-Core hyperthreaded CPU is mission critical, keep reading.

Don't make the mistake of saying this code is "multi-threaded" or "multi-core" because it's not. C code is still processing this code in an iterative first-in-first out queue-like way. The 4th addition must wait for the 3rd, and 3rd must wait for the 2nd. Your CPU is twiddling its thumbs while this iteration occurs. If you want your sixteen-core CPU under your desk maxing out its CPU use to 100% while this operation is executing, then there is no escape: you must stop and re-define this problem in a multi-threaded and multi-core oriented way. Multi-thread and multi-core is beyond the scope of this answer, the easiest way is to define your octave code to spawn 8 separate parallel job1.m through job8.m files that run all at the same time, have all of them process 1/8th of the task at hand, at the end wait for all to finish then rejoin the answer. GNU Octave Vectorization here does NOT equal Multi-threaded down on the metal.

Solution 4:

Simpler way, As Nasser Pointed out, the following octave code:

f=@(x) x+5;
A = [1, 0, -1; 3, 4, 5];
result = f(A)
result

applies (x+5) to every element passed in, it prints:

result =
    6    5    4
    8    9   10