How pass variables by reference to a Scilab function - function

I want to have a Scilab function which is able to alter its input variables, For example in C I could have
void double(int* x){
*x *= 2;
return;
}
There are intppty, funptr, addinter, istk, sadr and stk in Scilab which seem to be relevant, however I can't find any working example. Scilab does have a pointer type (i.e. 128). I would appreciate if you could help me figure this out.
P.S.1. I have also mirrored this question here on Reddit.
P.S.2. Scilab also have intersci, SWIG, fort, external, call, API_Scilab/gateway which can interface C/C++ functions or Fortran subroutines. Unfortunately intersci has been deprecated and SWIG seems to be only for Linux with limited C++ compatibility.
P.S.3. scilab has function overloading which can do stuff with the functions defined by deff and a combination of %,<...>,_... syntax.
P.S.4. The way API_Scilab/gateway works, is basically you dvelop the code using functionalities provided bu the header file api_scilab.h, compile it with ilib_build, write a loader*.sce script and then load it with exec.
P.S.5. supposedly one should be able to install mingw compiler with
atomsInstall('mingw'); atomsLoad('mingw');
However I am not able to get it to work as I have explained here.

This is possible by using, e.g. a C++ Scilab 6 gateway (example needs a compiler on the machine, it should not be a problem for Linux and OSX users):
gw=[
"#include ""double.hxx"""
"#include ""function.hxx"""
"types::Function::ReturnValue sci_incr(types::typed_list &in, int _iRetCount,"
" types::typed_list &out)"
"{"
" if (in.size() != 1 || in[0]->isDouble() == false) {"
" throw ast::InternalError(""Wrong type/number of input argument(s)"");"
" }"
" types::Double *pDbl = in[0]->getAs<types::Double>();"
" double *pdbl = pDbl->get();"
""
" for (int i=0; i < pDbl->getSize(); i++) (*pdbl) += 1.0;"
""
" return types::Function::OK;"
"}"];
cd TMPDIR;
mputl(gw,TMPDIR+"/sci_incr.cpp");
ulink
ilib_build("incr", ["incr" "sci_incr" "cppsci"],"sci_incr.cpp", [])
exec loader.sce
After compilation/link of the interface, you can have the following behavior:
--> x=1
x =
1.
--> incr(x)
--> x
x =
2.
However, don't consider this as a feature, because the Scilab language has not been designed to use it !

For my understanding this is not possible, in scilab input arguments are in the right side of the function and outputs are on the left side. See https://help.scilab.org/docs/6.0.2/en_US/function.html
[output,...] = function(input,...)
So, if you would like an input/output argument you have to assign the input argument to the output one inside your function.
[c] = f1(a, b)
c = a + b
endfunction
And you call it using same variable as input and output argument:
d = 10;
d = f1(d, 1);

Related

Octave doesn't disp my values, and only stores in ans variable [duplicate]

I've a very newbie octave question.
Running this code in octave console is working fine:
function fibo = recfibo(n)
if ( n < 2 )
fibo = n;
else
fibo = recfibo(n-1) + recfibo(n-2);
endif
endfunction
disp(recfibo(5))
By inserting this code in an external file named for example file.m, and executing it through octave file.m an error occurs:
warning: function name 'recfibo' does not agree with function filename
'/Users/admin/Google Drive/file.m'
error: 'n' undefined near line 2 column 8 error: called from
octave at line 2 column 3
How should I resolve this particular problem?
Add 1; as the first line of the file:
1;
function fibo = recfibo(n)
if ( n < 2 )
fibo = n;
else
fibo = recfibo(n-1) + recfibo(n-2);
endif
endfunction
disp(recfibo(5))
Any M-file that starts with a function definition is a function M-file, not a script M-file. By adding a meaningless statement to the top, you turn it into a script.
In MATLAB (since fairly recently), a script M-file can define functions at the end of the script. There you'd put the disp line at the top of the file, and have the function block at the end, without any script lines after it. However, Octave requires functions to be defined before you use them, hence it has to come before the script line that uses the function. Octave allowed the definition of functions within a script file before MATLAB introduced that feature, hence their implementation is not compatible with that of MATLAB.
As stated in the answer provided by #CrisLuengo here you have created a function file instead of a script file and they are treated differently in Octave. Because it is a function file Octave executes it by calling the function it defines with no arguments and nargout = 0. So you will get an error that n is undefined.
Another problem is that the function name 'recfibo' does not agree with function filename 'file'. In such cases Octave internally changes the name of the function to the name of the function file so the name is changed to 'file'. Therefor Octave and the function itself will forget the original function name and unfortunately the function cannot call itself recursively!
I like the #CrisLuengo 's answer but I think the more idiomatic and preferable way is always using function files instead of script files, though the script file solution is the only solution that works in previous Octave versions (Octave 3.X).
You can change your code to:
function file
disp(recfibo(5))
endfunction
function fibo = recfibo(n)
if ( n < 2 )
fibo = n;
else
fibo = recfibo(n-1) + recfibo(n-2);
endif
endfunction

Do functions always require their own separate files? [duplicate]

I've a very newbie octave question.
Running this code in octave console is working fine:
function fibo = recfibo(n)
if ( n < 2 )
fibo = n;
else
fibo = recfibo(n-1) + recfibo(n-2);
endif
endfunction
disp(recfibo(5))
By inserting this code in an external file named for example file.m, and executing it through octave file.m an error occurs:
warning: function name 'recfibo' does not agree with function filename
'/Users/admin/Google Drive/file.m'
error: 'n' undefined near line 2 column 8 error: called from
octave at line 2 column 3
How should I resolve this particular problem?
Add 1; as the first line of the file:
1;
function fibo = recfibo(n)
if ( n < 2 )
fibo = n;
else
fibo = recfibo(n-1) + recfibo(n-2);
endif
endfunction
disp(recfibo(5))
Any M-file that starts with a function definition is a function M-file, not a script M-file. By adding a meaningless statement to the top, you turn it into a script.
In MATLAB (since fairly recently), a script M-file can define functions at the end of the script. There you'd put the disp line at the top of the file, and have the function block at the end, without any script lines after it. However, Octave requires functions to be defined before you use them, hence it has to come before the script line that uses the function. Octave allowed the definition of functions within a script file before MATLAB introduced that feature, hence their implementation is not compatible with that of MATLAB.
As stated in the answer provided by #CrisLuengo here you have created a function file instead of a script file and they are treated differently in Octave. Because it is a function file Octave executes it by calling the function it defines with no arguments and nargout = 0. So you will get an error that n is undefined.
Another problem is that the function name 'recfibo' does not agree with function filename 'file'. In such cases Octave internally changes the name of the function to the name of the function file so the name is changed to 'file'. Therefor Octave and the function itself will forget the original function name and unfortunately the function cannot call itself recursively!
I like the #CrisLuengo 's answer but I think the more idiomatic and preferable way is always using function files instead of script files, though the script file solution is the only solution that works in previous Octave versions (Octave 3.X).
You can change your code to:
function file
disp(recfibo(5))
endfunction
function fibo = recfibo(n)
if ( n < 2 )
fibo = n;
else
fibo = recfibo(n-1) + recfibo(n-2);
endif
endfunction

Wrong output and with a special sign "[square]" although same code works in "Octave-online"

Octave 6.1.0 (GUI)
This is a spin-off from Octave: How to turn a vector of integers into a cell array of strings?.
>> a = 1:3;
>> cellstr(int2str(a(:)))
ans =
{
[1,1] = "[square]"
}
While the output should be:
ans =
{
[1,1] = 1
[2,1] = 2
[3,1] = 3
}
octave-online.net:
How to fix this?
Only for your information and not as an answer, a workaround without this issue would be cellstr(num2str(a(:))).
This is caused by a terrible beginner's mistake.
The first helping comment under the question has already shown the way.
If the online Octave is totally different from your GUI, it is probably your fault.
In order to find the problem, check the functions that might cause the difference:
>> which('num2str')
'num2str' is a function from the file C:\Users\USERNAME\AppData\Local\Programs\GNU Octave\Octave-6.1.0\mingw64\share\octave\6.1.0\m\general\num2str.m
>> which('cellstr')
'cellstr' is a built-in function from the file libinterp/octave-value/ov-cell.cc
which('int2str')
>> which('int2str')
'int2str' is a variable`
Since I have for some unknown reason tested only other functions, but not the 'int2str', I accidentally found out about the error when using the shadowed function instead:
>> strcat('x', num2cell(int2str(1:10)))
error: int2str(10): out of bound 3 (dimensions are 1x3)
(note: variable 'int2str' shadows function)
For whatever reason, I had accidentally shadowed the function by assigning int2str = [1:3], leading to the strange behaviour.
Arbeitsumgebung = work environment:

How do I set a function to a variable in MATLAB

As a homework assignment, I'm writing a code that uses the bisection method to calculate the root of a function with one variable within a range. I created a user function that does the calculations, but one of the inputs of the function is supposed to be "fun" which is supposed to be set equal to the function.
Here is my code, before I go on:
function [ Ts ] = BisectionRoot( fun,a,b,TolMax )
%This function finds the value of Ts by finding the root of a given function within a given range to a given
%tolerance, using the Bisection Method.
Fa = fun(a);
Fb = fun(b);
if Fa * Fb > 0
disp('Error: The function has no roots in between the given bounds')
else
xNS = (a + b)/2;
toli = abs((b-a)/2);
FxNS = fun(xns);
if FxNS == 0
Ts = xNS;
break
end
if toli , TolMax
Ts = xNS;
break
end
if fun(a) * FxNS < 0
b = xNS;
else
a = xNS;
end
end
Ts
end
The input arguments are defined by our teacher, so I can't mess with them. We're supposed to set those variables in the command window before running the function. That way, we can use the program later on for other things. (Even though I think fzero() can be used to do this)
My problem is that I'm not sure how to set fun to something, and then use that in a way that I can do fun(a) or fun(b). In our book they do something they call defining f(x) as an anonymous function. They do this for an example problem:
F = # (x) 8-4.5*(x-sin(x))
But when I try doing that, I get the error, Error: Unexpected MATLAB operator.
If you guys want to try running the program to test your solutions before posting (hopefully my program works!) you can use these variables from an example in the book:
fun = 8 - 4.5*(x - sin(x))
a = 2
b = 3
TolMax = .001
The answer the get in the book for using those is 2.430664.
I'm sure the answer to this is incredibly easy and straightforward, but for some reason, I can't find a way to do it! Thank you for your help.
To get you going, it looks like your example is missing some syntax. Instead of either of these (from your question):
fun = 8 - 4.5*(x - sin(x)) % Missing function handle declaration symbol "#"
F = # (x) 8-4.5*(x-sin9(x)) %Unless you have defined it, there is no function "sin9"
Use
fun = #(x) 8 - 4.5*(x - sin(x))
Then you would call your function like this:
fun = #(x) 8 - 4.5*(x - sin(x));
a = 2;
b = 3;
TolMax = .001;
root = BisectionRoot( fun,a,b,TolMax );
To debug (which you will need to do), use the debugger.
The command dbstop if error stops execution and opens the file at the point of the problem, letting you examine the variable values and function stack.
Clicking on the "-" marks in the editor creates a break point, forcing the function to pause execution at that point, again so that you can examine the contents. Note that you can step through the code line by line using the debug buttons at the top of the editor.
dbquit quits debug mode
dbclear all clears all break points

How to pass a function as argument

I'm using Scilab and I'm trying to make a function like the following:
function p = binary_search(myf,a,b)
The target is to make a binary_search to find such p that: myf(p) = 0 in [a,b].
I want to do something like this:
root = binary_search("x^3 - 10",1,2)
Where the first string is a definition of a function.
The only way I found is defining a function called x3:
function x = x3(p)
x = p^3 - 10;
endfunction
and then, inside binary_search, do something like:
fa = x3(a);
Any ideas?
Thank You!
If you have defined the function f(x) = x^3 - 10 , either using deff('y=f(x)','y=x^3-10') or the regular "function ... endfunction" syntax, then you can simply pass f as an argument: define
function r = binary_search(f,a,b)
% do the binary search here and store the result in r
endfunction
Then you can call
---> binary_search(f, 1, 2)
which works fine in SciLab.
In MATLAB/octave, the interpreter considers " f " as an equivalent for f(), i.e., it would execute the function f without arguments, which will result in an error "x undefined". To avoid this, you have to type an # in front of f:
---> binary_search( #f, 1, 2) %% in MATLAB/octave
Functions in Scilab can be passed as arguments to other functions. Therefore, if you have one function, f:
function y=f(x)
y = x^3 - 10
endfunction
you are free to pass that to another function,
root = binary_search("x^3 - 10",1,2)
deff is simply a way to quickly define a function- usually inline on the interpreter.
Alternatively, you can also pass an expression as a string to a function and have that evaluated using the evstr command:
function p = binary_search(expression, a, b)
evstr expression
//Rest of your code
endfunction
You would implement this on the interpreter thus:
expression = "a^3 - 10"
root = binary_search(expression, 1, 2)
I found a solution:
In the main window (the interpreter), I define the function like:
deff('[y] = square(x)','y=x^2')
Then, I call
bi(square,0,2)
In the function, I just do 'f(x)':
function [x] = bi(f,a,b)
fa = f(a);