octave log2 function shows error - octave

I am using log2 function in Octave to calculate log2 values of a simple array.
>> x = [1:5]
x =
1 2 3 4 5
>> log2(x)
error: invalid use of script D:\All_Data\my_data\backup3\backup3\tech\DSP\log2.m in index expression
I am not sure why Octave is bailing out with error in this case ...

You probably have a script that is called log2.m in your running directory, which prevents octave from calling its own log2 function.
I assume that is the case because D:\All_Data\my_data\backup3\backup3\tech\DSP\log2.m
doesn't look like a path where standard octave library functions would be installed.
I recommend changing the name of the script in your running directory.

Related

Run Octave function with one argument from batch

I am trying to run an octave function from a batch file. The function is well written given how it works when launched from within the Octave GUI.
The batch file, other than pointing to the octave function, defines the only argument needed by it.
A while back this was not a function but a simple Octave script and the commands used were ok.
The only issue I am encountering now is being able to pass the variable calculated by the batch file onto the octave function.
I have recently written an octave function to do some file management. It requires only one input from the user:
function replace_TMM (file_base)
where file_base is a string to specify what directory I am working on. So it has to be something like "Z:" or "I:" or so on.
I am quite sure that the function is well written since I am able to use it from Octave GUI without any issues.
The fact is that I would like to run this function from a batch file. Inside this batch file I wrote:
SET a=%cd:~0,2%
This command is able to identify the working directory so "a" will be equal to "Z:" or similars.
Now my issue is telling the batch file to evaluate the octave function using "a" as its input argument.
I tried stuff like:
"C:\Program Files\GNU Octave\Octave-7.3.0\mingw64\bin\octave-cli.exe" -q --eval _03_REPLACE_V04("'%cd:~0,2%'")
which does not seem to work. This kind of solution gives a syntax error at batch level, it is not even able to enter the octave file.
If I instead try something like:
"C:\Program Files\GNU Octave\Octave-7.3.0\mingw64\bin\octave-cli.exe" -q _03_REPLACE_V04.m Z:
It is able to enter the octave file but it does not process the function, just skips over it to get to the end of the script.
Same goes if I try the following:
"C:\Program Files\GNU Octave\Octave-7.3.0\mingw64\bin\octave-cli.exe" _03_REPLACE_V04.m -"Z:"
In brief I bvelieve that the function itself works, it is only a matter of passing a variable from the batch to the octave.
Would really appreciate some help, thanks in advance.
UPDATE 1
I have done what was suggested by #Dariush Gavari and used the following syntax:
"C:\Program Files\GNU Octave\Octave-7.3.0\mingw64\bin\octave-cli.exe" -q --eval "replace_TMM('%a%')"
This gets me the following error message:
error: 'replace_TMM' undefined near line 1, column 1
I believed that it was because it was not ablòe to find the script containing the function. This is saved in a file called _03_REPLACE_V04.m
For this reason I have tried with
"C:\Program Files\GNU Octave\Octave-7.3.0\mingw64\bin\octave-cli.exe" -q --eval _03_REPLACE_V04.m "replace_TMM('%a%')"
Leading to the following error:
error: --eval "CODE" and script file are mutually exclusive options
usage: octave [-HVWdfhiqvx] [--debug] [--doc-cache-file file] [--echo-commands]
[--eval CODE] [--exec-path path] [--experimental-terminal-widget]
[--gui] [--help] [--image-path path] [--info-file file]
[--info-program prog] [--interactive] [--line-editing] [--no-gui]
[--no-history] [--no-init-file] [--no-init-path] [--no-line-editing]
[--no-site-file] [--no-window-system] [--norc] [-p path]
[--path path] [--persist] [--server] [--silent] [--traditional]
[--verbose] [--version] [file]
I believed that the problem could also have been having the functional nd the file with two different names. To solve this I have kept the same file name but changed the function to match it:
function _03_REPLACE_V04 (file_base)
Then in the batch:
"C:\Program Files\GNU Octave\Octave-7.3.0\mingw64\bin\octave-cli.exe" -q --eval "_03_REPLACE_V04('%a%')"
Leading to:
warning: function '_03_REPLACE_V04' defined within script file '\99_TOOLS\OCTAVE_FILES\_03_REPLACE_V04.m'
error: invalid call to script \99_TOOLS\OCTAVE_FILES\_03_REPLACE_V04.m
error: called from
_03_REPLACE_V04
In other words still no way of making it work. :)
Octave provides the argv function, which returns a cellstring array of all arguments passed to the octave executable at the time of launch, or in the case where it was used to launch a script, then this is the script's arguments.
So presumably all you have to do to get your directory from within octave is argv(){1}
If you would like to convert your filename to an absolute filename, you could also do this from within octave via the make_absolute_filename function.
Incidentally, a very useful command you should know of in octave is the lookfor command. Writing lookfor arguments in the terminal returns a list with all functions which have the word "arguments" in their description; argv is at the top of that list.
You can then do help argv to see more details on that command.

Octave parallel package: User-defined function call issues

I have trouble calling a user-defined function with pararrayfun (likewise for parcellfun). When I execute the following code:
pkg load parallel
function retval = mul(x,y)
retval = x*y;
endfunction
vector_x = 1:2^3;
vector_y = 1:2^3;
vector_z = pararrayfun(nproc, #(x,y) mul(x,y), vector_x, vector_y)
vector_z = pararrayfun(nproc, #(x,y) x*y, vector_x, vector_y)
I get the following output:
vector_z =
-1 -1 -1 -1 -1 -1 -1 -1
vector_z =
1 4 9 16 25 36 49 64
That is, the call to the user-defined function does not seem to work, whereas the same as an anonymous function is working.
The machine is x86_64 with Debian bullseye and 5.10.0-1-amd64 kernel. Octave's version is 6.1.1~hg.2020.12.27-1. The pkg list command gives me:
Package Name | Version | Installation directory
--------------+---------+-----------------------
dataframe | 1.2.0 | /usr/share/octave/packages/dataframe-1.2.0
parallel *| 4.0.0 | /usr/share/octave/packages/parallel-4.0.0
struct *| 1.0.16 | /usr/share/octave/packages/struct-1.0.16
Funny thing is that the same code works flawless on armv7l with Debian buster and 4.14.150-odroidxu4 kernel. That is the call to the user-defined function and the anonymous function produce the output:
parcellfun: 8/8 jobs done
vector_z =
1 4 9 16 25 36 49 64
parcellfun: 8/8 jobs done
vector_z =
1 4 9 16 25 36 49 64
On that machine Octave's version is 4.4.1 and pkg list gives:
Package Name | Version | Installation directory
--------------+---------+-----------------------
dataframe | 1.2.0 | /usr/share/octave/packages/dataframe-1.2.0
parallel *| 3.1.3 | /usr/share/octave/packages/parallel-3.1.3
struct *| 1.0.15 | /usr/share/octave/packages/struct-1.0.15
What is wrong and how can I fix this behavior?
This is probably a bug, but do note that the new version of parallel has introduced a few limitations as per its documentation (also see the latest release news) which may relate to what's happening here.
Having said that, I want to clarify this sentence:
the call to the user-defined funtion does not seem to work, whereas the same as an anonymous function is working.
That's not what's happening. You're passing an anonymous function in both cases. It's just that the first calls mul inside, and the second calls mtimes.
As for your error (bug?) this may have something to do with mul being a 'command-line' function. It's not clear from the documentation if command-line functions are a limitation and this is simply an oversight in the docs, or if ill-treatment of command-line functions is a genuine bug. I think if you put it in its own file it should work fine. (and equally, if you do, it's worth passing it as a handle directly, rather than wrapping it inside another anonymous function).
Having said that, I think the -1's you see are basically "error returns" from inside pararrayfun's guts. The reason for this is the following: if instead of creating mul as a command-line function, you make it an anonymous function:
mul = #(x,y) x * y
Observe what the three calls below return:
x = pararrayfun( nproc, #(x,y) mul(x,y), vector_x, vector_y ) # now it works as expected.
x = pararrayfun( nproc, mul, vector_x, vector_y ) # same: mul is a valid handle expecting two inputs
x = pararrayfun( nproc, #mul, vector_x, vector_y ) # x=-1,-1,-1,-1,-1,-1,-1,-1
If you had tried the last command using normal array fun, you would have seen an error relating to the fact that you accidentally passed #mul instead of mul, when mul is a proper handle. In pararrayfun, it just does the calculation, and presumably -1 was the return value from an internal error.
I don't know exactly why a command-line function fails, but presumably it has something to do with the fact that pararrayfun creates separate octave instances under the hood, which need access to all function definitions, and perhaps command-line functions cannot be transfered / compiled in the new instance as easily as in the parent instance, because of the way they are created / compiled in the current session.
In any case, I think you'll solve your problem if instead of a command-line function definition, you create an external function or (if dealing with simple enough functions) a handle to an anonymous function.
However, I would still submit a bug to the octave bug tracker to help the project :)

openfig function unavailable in octave?

I was trying to the following line in octave as part of a GUI plot program.
if nargin == 0
warning off
fig = openfig(mfilename,'reuse');
warning on
But I'm getting the following error
error: 'openfig' undefined near line xx
Is this function not available in octave? How can I get it?
I tried posting this as a comment but it messed up the formatting, so posting as an answer instead, though its really more of a comment.
I can't replicate your error. If I run the following script to save 'Unitled.fig':
x = linspace (0, 2*pi, 200);
y = sin(x);
plot(x,y);
savefig(gcf);
and then run:
n = 0;
mfilename = 'Untitled'
if n == 0
warning off
fig = openfig(mfilename,'reuse');
warning on
endif
it works fine on my machine using Octave 5.2.0, though the 'reuse' option isn't mentioned in the Octave manual. Maybe the file you are trying to open is an incompatible format? Was it originally saved using Matlab?

How to load a user specified file in Octave

I have a very short script that I'm running in Octave and I want to read a user specified text file. It works on my 64-bit laptop, but not on my 32-bit one. The Octave version is 3.2.2.
plotinfra.m
filename=uiputfile
data=load(filename);
plot(data(:,1),data(:,2));
On my other laptop, this brings up a filesystem menu where I can choose the specific file to load. On this laptop, I see this error message instead:
error: uiputfile undefined near line 1 column 19 error: called from: error: plotinfra.m at line 1, column 17
If I hardcode filename with a path it works. I also tried using uigetfile and that did not work either.
Version 3.2.2 of Octave was released in 2009. When I enter edit uiputfile in Octave, at the top of the file I see the line:
## Copyright (C) 2010-2019 Kai Habel
Thus, it seems that this function was created after your release of Octave. This is the reason you get a "uiputfile undefined" error message.
You will have to upgrade your version of Octave to use this function.
I'm using Ubuntu 18.04 64Bit Linux Octave 4.2.2 see if this works for you. It will store the filename in the variable file_name and the path location in the variable path_dir
% create your dataset (exampledata)
x = (-1:0.1:1);
y = sin(x);
data = zeros(length(x),2);
data(:,1) = x;
data(:,2) = y;
% save data to file (your textfile)
save('-ascii','data2.txt','data');
%load textfile
%data2 = load('data2.txt'); %hard coded
[file_name,path_dir] = uigetfile('*.txt'); %pops up uibox choose data2.txt
data2 = load(strcat(path_dir,file_name)); %loads the file and the data
%plot data
plot(data2(:,1),data2(:,2));

Creating Function in Octave

I'm beginning with octave. I've created a file called squareThisNumber.m in My Documents with the following code:
function y = squareThisNumber(x)
y = x^2;
I set the directory to look at My Documents with
cd 'C:\Users\XXXX\My Documents'
I type "squareThisNumber(3)" into octave, and all I'm getting is "Error: 'squareThisNumber' undefined near line 3 column 1." What am I doing wrong?
EDIT:
When I type ls into octave, I get "error: ls: command exited abnormally with status 127". Did I not install Octave correctly?
This behavior sure does seem like there's a problem with octave's current working directory. Does the command dir or pwd also have the same problem?
But you might be able to ignore all of that by
addpath("C:\Users\XXXX\My Documents");
Did you place the end keyword at the end? Code example below works perfectly for me
https://saturnapi.com/fullstack/function-example
% Welcome to Saturn's MATLAB-Octave API.
% Delete the sample code below these comments and write your own!
function y = squareThisNumber(x)
y = x^2;
end
squareThisNumber(9)