Octave

Fixing Octave string compare

Problem:

You want to compare two strings in Octave like myString == "foobar" but you see an error message like

error: myscript.m: mx_el_eq: nonconformant arguments (op1 is 1x25, op2 is 1x6)
error: called from
    myscript.m at line 26 column 1

Solution:

You can’t compare strings using == in Octave!

Use strcmp like this: Instead of myString == "foobar" use

strcmp(myString, "foobar") == 1

 

Posted by Uli Köhler in Octave

Octave: Use ‘qt’ graphics_toolkit() if available, ‘gnuplot’ else

This code uses the "qt" graphics toolkit only if available and defaults to using "gnuplot" else:

gts = available_graphics_toolkits()
qt_available = any(strcmp(gts, 'qt'))
if qt_available
  graphics_toolkit("qt")
else
  graphics_toolkit("gnuplot")
endif

See Octave: Check if cell array of strings contains string for details on how to check if a string like "qt" is in a cell array of strings like the one returned by available_graphics_toolkits().

Posted by Uli Köhler in Octave

Octave: Check if cell array of strings contains string

If you have a cell array of strings in Octave like this:

arr = {"a", "bc", "def"}

you can check if it contains a specific string like "a" using

contains_a = any(strcmp(arr, 'a'))

Example:

arr = {"a", "bc", "def"}

contains_a = any(strcmp(arr, 'a'))
contains_x = any(strcmp(arr, 'x'))

disp(contains_a) # 1
disp(contains_x) # 0

 

Posted by Uli Köhler in Octave

Octave equivalent to Python’s print

In Python you can use print:

print("foobar")

whereas in Octave you can use disp:

disp("foobar")

You can print numbers using print in Python:

x = 1
print(x)

and also using disp in Octave:

x = 1
disp(x)

Note that you can use multiple argument to print in Python:

x = 1
print("The value of x is", x)

whereas in Octave you need to use disp together with cstrcat:

disp(cstrcat("The value of x is ", num2str(x)))

 

Posted by Uli Köhler in Octave

Running a function for each file in Octave

Often if you have a directory of data files, you want to run a processing or parsing function for every file in that directory.

This snippet allows you to select files using a glob pattern (e.g. data/*.txt)

runForEachFile.m

% Run func(filepath, fileId) for each file and fclose() it afterwards
% Usage example: runForEachFile(@parseTXT, "data/*.txt")
function runForEachFile(func, pattern)
  files = glob(pattern);
  for i = 1:numel(files)
    file = files{i};
    % Open file...
    fid = fopen(file);
    % Run function
    func(file, fid);
    % Cleanup
    fclose(fid);
  endfor
end

Usage example:

% Define utility handler function to only display the filename
function dispFirst(x, y) disp(x) endfunction

% Essentially displays a list of filenames,
% with the opened files being ignored by dispFirst.
% Opens only one file at a time!
runForEachFile(@dispFirst, "data/*.txt")
Posted by Uli Köhler in Octave

String startsWith function in Octave

This function is the equivalent of Python’s startsWith function and works for strings:

startsWith.m:

% Check if a string starts with a given prefix
% Returns 1 if s starts with prefix, 0 else
function retval = startsWith(s, prefix)
  n = length(prefix);
  if n == 0 # Empty prefix
    retval = 1; # Every string starts with empty prefix
    return
  endif
  retval = strncmp(s, prefix, n);
endfunction

Examples:

>> startsWith("myString", "my")
ans = 1
>> startsWith("myString", "abc123")
ans = 0
>> startsWith("myString", "My")
ans = 0
>> startsWith("myString", "")
ans = 0

 

Posted by Uli Köhler in Octave

Octave: How to create a function file from a function?

You have an Octave function and you want to move it into a separate file.

First, you need to know that a function file can only contain ONE function and that function needs to be named just like the file.

Therefore, if your function is called myfunc, you absolutely need to move it to a file called myfunc.m, or else Octave won’t find it.

Creating the file is pretty simple: Just paste the function into the file. You must ensure that the first statement in the file is function ... (else, it will be treated as a script file, not a function file) (any number of comments and empty lines is OK though)

Example: myfunc.m:

function retval = myfunc(n)
  retval = n + 5
endfunction

After you have saved that file, you can immediately use myfunc() in Octave:

>> myfunc(3)
retval =  8
ans =  8

Octave will automatically use the updated version in case you make changes to myfunc.m

Posted by Uli Köhler in Octave

How to concatenate strings in Octave

In order to concatenate strings, in GNU Octave, use this snippet:

% Concatenate and assign to a variable named "concatenated"
concatenated = strcat("test", "123");
% OPTIONAL: Show the value of the "concatenated" variable in the terminal
disp(concatenated); % Displays "test123" (without quotes) in the terminal

Similarly, you can concatenate three or more strings:

strcat("test", "123", "456"); # test123456

You don’t have to use literal strings, you can also use variables instead:

mystr = "xyz";
strcat("test", mystr, "456"); # testxyz456

Alternatively you can use this short syntax (no commata between the strings!):

concatenated = ["test" "123"]

% Show the value
disp(concatenated);
Posted by Uli Köhler in Octave

Octave: How to print a string or number to the terminal

In order to print a string to the terminal in GNU Octave use

disp("Hello world");

This prints:

>> disp("Hello world");
Hello world

If you want to display a number/variable in addition to the string, use this snippet:

mynumber = 5;
disp("Hello world, mynumber="), disp(mynumber);

This prints:

>> mynumber = 5;
>> disp("Hello world, mynumber="), disp(mynumber);
Hello world, mynumber=
 5

Alternatively, you can use printf, which I recommend for all but the most simple cases:

>> printf ("Hello world, mynumber=%d\n", mynumber);
Hello world, mynumber=5

Don’t forget to add \n to the end of the printf format string to end the line, and use the correct format specifier (e.g. %d in this case for integers – see the printf docs for details).

Posted by Uli Köhler in Octave