How to execute multi-line Maxima code from Octave / Matlab - matlab

I can execute Maxima code from Octave like this and it works:
mm=maxima("diff(a*x^3-b*x^2+x+d,x,1)")
but how can I execute multi line commands?
Example code below that works in Maxima
kill(all)$
numer:true$
ratprint:false$
angle_in_bits:3779$
total_fs:18136$
s:solve(angle_deg=(angle_in_bits/total_fs*360),angle_deg)$
round(s);
[round(angle_deg)=75]
When I try the code below in Octave I get syntax errors
mm=maxima("kill(all)$
numer:true$
ratprint:false$
angle_in_bits:3779$
total_fs:18136$
s:solve(angle_deg=(angle_in_bits/total_fs*360),angle_deg)$
round(s);")
Errors that I get:
>>> mm=maxima("kill(all)$
numer:true$
ratprint:false$
angle_in_bits:3779$
total_fs:18136$
s:solve(angle_deg=(angle_in_bits/total_fs*360),angle_deg)$
round(s);")
error: unterminated character string constant
parse error:
syntax error
>>> mm=maxima("kill(all)$
^
>>> _ide_reload_variables_list( whos() );
error: 'numer' undefined near line 1 column 1
error: invalid base value in colon expression
error: 'ratprint' undefined near line 1 column 1
error: invalid base value in colon expression
parse error:
syntax error
>>> angle_in_bits:3779$
^
parse error:
syntax error
>>> total_fs:18136$
^
parse error:
syntax error
>>> s:solve(angle_deg=(angle_in_bits/total_fs*360),angle_deg)$
^
error: unterminated character string constant
parse error:
syntax error
>>> round(s);")
^

Thanks to Fred Senese and rayryeng for the assist.
I know someone may need this so here's some example code. This bit of code allows you to directly access maxima's symbolic solver from octave (allows you to execute multiple lines of maxima's commands). Since octave doesn't have a good symbolic solver yet this will come in handy for another person down the line.
mm=maxima("(kill(all), numer:true, ratprint:false, angle_in_bits:3779, total_fs:18136, s:solve(angle_deg=(angle_in_bits/total_fs*360),angle_deg),(s))")
%mm = '[angle_deg = 75.01323334803705]';
[si ei xt mt] = regexp(mm, '(\d)*(\.)?(\d)*');
number = str2num(mt{1})
>>>number = 75.013

I will suppose here that you are using QtOctave which I am guessing from googling your error message "_ide_reload_variables_list( whos() );"
If this is not so, none of the following may apply to your question.
typing help maxima at the prompt points me to a file /usr/share/qtoctave/scripts_octave/maxima.m
with this contents:
function result=maxima(command)
in="";
in=sprintf("echo \"string(%s);\"|maxima --very-quiet", command);
[status,result]=system(in);
%if(status!=0) result=""; endif;
result = deblank ( strjust ( strrep (result, "%", "") ,"left") );
endfunction
Which tells me that maxima is called via octave's function system in a very special way that is not allowing for multiple commands in maxima.
modifying the assignment of in in the way below would allow you to call the function maxima now with a cell array of commands maxima({command_1,command_2}) where command_i are strings.
in=['echo ', sprintf('\"%s;\" ',command{:}), '| maxima --very-quiet'];
Please note that the function system still returns only one output, the one that is sent to standard out by maxima.
This may also be of interest for you as it describes methods of octave's interaction with subprocesses.
I am not sure if this helping much as I think the modification provided by me is only of very superficial use, but maybe it helps you to understand better what octave is doing if you tell it maxima(something). It helped me.
Last but not least as far as I know there is no real interface between octave (or matlab) and maxima. I hope someone will correct me if I am wrong about that.

I have Octave and Maxima in my Linux laptop (Ubuntu). There exist system -function in Octave, which could be used to run terminal -commands.
In terminal it is possible to call maxima functions by using pipe
(add quit(); to the end of maxima command) :
$ echo "factor(12345); quit();" | maxima
Maxima 5.41.0 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.12
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) (%o1) 3 5 823
$
In Octave' system -commad use double "" inside "-marks to get " :
[status,output]=system("echo ""factor(565);quit();""|maxima")
status = 0
output =
Maxima 5.41.0 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.12
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) (%o1) 5 113
Extra txt could be cutted out from the output -string in Octave. Use Maxima's properties to run it's commands from a script file, and the script could be created in Octave.
Br. Juha (juhap.karjalainen#mail.suomi.net)

Related

How to write a single Octave script with function definitions compatible with Matlab scripts?

If I write this:
clc
clear
close all
format long
fprintf( 1, 'Starting...\n' )
function results = do_thing()
results = 1;
end
results = do_thing()
And run it with Octave, it works correctly:
Starting...
results = 1
But if I try to run it with Matlab 2017b, it throws this error:
Error: File: testfile.m Line: 13 Column: 1
Function definitions in a script must appear at the end of the file.
Move all statements after the "do_thing" function definition to before the first local function
definition.
Then, if I fix the error as follows:
clc
clear
close all
format long
fprintf( 1, 'Starting...\n' )
results = do_thing()
function results = do_thing()
results = 1;
end
It works correctly on Matlab:
Starting...
results =
1
But now, it stopped working with Octave:
Starting...
error: 'do_thing' undefined near line 8 column 11
error: called from
testfile at line 8 column 9
This problem was explained on this question: Run octave script file containing a function definition
How to fix it without having to create a separate and exclusive file for the function do_thing()?
Is this issue fixed on some newer version of Matlab as 2019a?
The answer is in the comments, but for the sake of clarity:
% in file `do_thing.m`
function results = do_thing()
results = 1;
end
% in your script file
clc; clear; close all; format long;
fprintf( 1, 'Starting...\n' );
results = do_thing();
Accompanying explanatory rant:
The canonical and safest way to define functions is to define them in their own file, and make this file accessible in octave / matlab's path.
Octave has supported 'dynamic' function definitions (i.e. in the context of a script or the command-line) since practically forever. However, for the purposes of compatibility, since matlab did not support this, most people did not use it, and quite sensibly relied on the canonical way instead.
Matlab has recently finally introduced dynamic function definitions too, but has opted to implement them explicitly in a way that breaks compatibility with octave, as you describe above. (rant: this may be a coincidence and an earnest design decision, but I do note that it also happens to go against prior matlab conventions regarding nested functions, which were allowed to be defined anywhere within their enclosing scope).
In a sense, nothing has changed. Matlab was incompatible with advanced octave functionality, and now that it has introduced its own implementation of this functionality, it is still incompatible. This is a blessing in disguise. Why? Because, if you want intercompatible code, you should rely on the canonical form and good programming practices instead of littering your scripts with dynamic functions, which is what you should be doing anyway.
Octave's implementation of local functions in scripts is different from Matlab's. Octave requires that local functions in scripts be defined before their use. But Matlab requires that local functions in scripts all be defined at the end of the file.
So you can use local functions in scripts on both applications, but you can't write a script that will work on both. So just use functions if you want code that will work on both Matlab and Octave.
Examples:
Functions at end
disp('Hello world')
foo(42);
function foo(x)
disp(x);
end
In Matlab R2019a:
>> myscript
Hello world
42
In Octave 5.1.0:
octave:1> myscript
Hello world
error: 'foo' undefined near line 2 column 1
error: called from
myscript at line 2 column 1
Functions before use
disp('Hello world')
function foo(x)
disp(x);
end
foo(42);
In Matlab R2019a:
>> myscript
Error: File: myscript.m Line: 7 Column: 1
Function definitions in a script must appear at the end of the file.
Move all statements after the "foo" function definition to before the first local function definition.
In Octave 5.1.0:
octave:2> myscript
Hello world
42
How it works
Note that technically the functions here in Octave are not "local functions", but "command-line functions". Instead of defining a function that is local to the script, they define global functions that come into existence when the function statement is evaluated.
The following code works on both Matlab and Octave:
if exist('do_nothing') == 0
disp('function not yet defined, run script again')
else
do_nothing
end
%====
function results = do_nothing()
results = 1;
end
When run on octave, the first attempt exits with the message, but subsequent attempts succeed. On Matlab, it works the first time. While this works on both platforms, it is less than ideal, since it requires that much of the script code be placed inside an "if" statement block.

Strange syntax error

I'm new to MATLAB, and I have the following problem:
I have the line:
[~, j] = min(matrix);
I don't understand what the ~ sign is for(I have to learn this code..) and the error is:
Expression or statement is incorrect--possibly unbalanced (, {, or [.
What can be the reason?
Another question, suppose I have got a file.m and inside of it I have the declaration:
methods (Static)
function var = func(n, d)
How do I call this function with the 2 parameters from the command windows?
i dont understand whats for ~ sign
Discard first returning output, it is not going to be used.
What can be the reason?
What version of Matlab do you use? This syntax has only been part of MATLAB since about R2009b or so.
How do i call this function func with the 2 parameters from the command windows?
Yes, otherwise - http://www.mathworks.com/help/matlab/matlab_prog/support-variable-number-of-inputs.html

Unexpected matlab expression in function

I have the following call to a function:
callfun(I1, I2, [X Y ones(n,1)], w, m)
But, I'm getting:
Error: File: callfun.m Line: 20 Column: 3
Unexpected MATLAB expression.
Why is that?
Thanks.
The error says, that your function callfun has a syntax error in line 20. Probably some character which is not allowed.
It can be also a problem of duplicated function definition. A function inside callfun.m may have the same name as a built-in MATLAB function, what yields an error.
From http://www.mathworks.com/matlabcentral/answers/214993-how-to-solve-error-unexpected-matlab-expression-workspacefunc-287:
Do you have any user-defined functions called builtin, strjoin, or strsplit? MATLAB has these defined internally, and having any outside functions that shadow these built-in ones would result in this error. If you are unsure if you have created such functions, typing the command:
>>which functionName -all
will show you the path to all items on the MATLAB path with the name "functionName"

inline iPython call to system

I really like to use system shell commands in iPython. But I was wondering if it is possible to loop over the returned values from a call to e.g. !ls. This works:
files = !ls ./*_subcell_cooc.txt
for f in files:
print f
But this does not:
for f in ( !ls ./*_subcell_cooc.txt):
print f
Error is:
File "<ipython-input-1-df2bc72907d7>", line 5
for f in ( !ls $ROOT/*_subcell_cooc.txt):
^
SyntaxError: invalid syntax
No it is not possible, the syntax var = !something is special cased in IPython. It is not valid python syntax, and we will not extend for loops and so on to work with it.
You can do assignment as you show in your first example, but using glob,os and other real python module to do that will be more robust, not much harder, and also work outside of IPython...
For the anecdote Guido was really not happy with IPython half-shell syntax when he saw it last time at SciPy2013.
(Also it uppercase I in IPython please.)

Octave : Index exceeds matrix dimensions

I wrote the following function in a file named conditionals.m:
function result = conditionals(category, feature)
result=5;
end
I call this function from Octave's command line:
v=conditionals(3,4)
I get the following error:
error : A(I) : Index exceeds matrix dimension.
Whats wrong here?
The error:
error : A(I) : Index exceeds matrix dimension.
Indicates that octave thinks that conditionals is a matrix, not a function.
Octave probably doesn't know that conditionals is a function - and instead it's treating it as a matrix.
Have you checked to see if the function is in Octave's search path?
This works for me.
octave> function result = conditionals (category, feature)
> result = 5;
> endfunction
octave> v = conditionals (3, 4)
v = 5
The error suggests that you have a variable with the same name as the function. Type whos at the Octave prompt to see a list of defined variables. If you see one named conditionals, remove it with clear conditionals
Also, if conditionals is a conditionals.m file, make sure it's on the function search path. Run path at the Octave prompt to see the function search path. Run which conditionals at the command prompt to see where the function is located.
It happened to me as well and it can happen on any command, regardless of the command name. When I run the PS1(">>"); to change the command prompt in Ovtave, I got the same error.
octave-3.2.3.exe:9> PS1(">>");
error: A(I): Index exceeds matrix dimension.
As others also mentioned, this error fires when there is a parameter with the same command name. It happens when we mistakenly enter the command with wrong syntax and hence, octave run the command and produce a variable with your command name that overload the internal command.
You can verify this status by who command. If you can see the same variable name as your command here, you have to remove it. Use clear variable_name to remove the variable.
Here is my output for PS1 command.
Hope it helps.