summaryrefslogtreecommitdiffstats
path: root/scilab_doc
diff options
context:
space:
mode:
authorFrancois Delebecque <Francois.Delebecque@inria.fr>2004-09-23 14:13:37 +0000
committerFrancois Delebecque <Francois.Delebecque@inria.fr>2004-09-23 14:13:37 +0000
commit58189be3678e83c70631afb153b283ba9b980cbd (patch)
tree64cce2949cc39c6b36c89d2851fa73b5c980f7d5 /scilab_doc
parenta0d9d653d9b36ed1c84402ea7d0a60dea9424622 (diff)
downloadscilab-58189be3678e83c70631afb153b283ba9b980cbd.zip
scilab-58189be3678e83c70631afb153b283ba9b980cbd.tar.gz
new
Diffstat (limited to 'scilab_doc')
-rwxr-xr-xscilab_doc/intro/chap6.tex723
1 files changed, 429 insertions, 294 deletions
diff --git a/scilab_doc/intro/chap6.tex b/scilab_doc/intro/chap6.tex
index 3aea0de..a21f156 100755
--- a/scilab_doc/intro/chap6.tex
+++ b/scilab_doc/intro/chap6.tex
@@ -1,15 +1,4 @@
1% Copyright INRIA 1\chapter{Interfacing C or Fortran programs}
2
3%\documentclass[11pt]{article}
4%\textwidth=6in
5%\textheight=8.5in
6%\oddsidemargin=.30in%.25in
7%\evensidemargin=.30in%.25in
8%\topmargin=-.25in
9%\parskip.3cm
10%\begin{document}
11
12\chapter{Interfacing C or Fortran programs with Scilab}
13 2
14Scilab can be easily interfaced with Fortran or C programs. 3Scilab can be easily interfaced with Fortran or C programs.
15This is useful to have faster code or to use specific numerical 4This is useful to have faster code or to use specific numerical
@@ -38,31 +27,30 @@ and then to interactively call
38the linked routine by {\tt call}\index{call@{\tt call}} primitive 27the linked routine by {\tt call}\index{call@{\tt call}} primitive
39which transmits Scilab variables (matrices or strings) to the linked program 28which transmits Scilab variables (matrices or strings) to the linked program
40and transforms back the output parameters into Scilab variables. 29and transforms back the output parameters into Scilab variables.
30Note that all the parameters of the routine called by the {\tt call}
31primitive must be pointers. In particular Fortran routines can be called
32using the {\tt call} primitive.
33
41Note that ode/dae solvers and non linear optimization primitives 34Note that ode/dae solvers and non linear optimization primitives
42can be directly used with C or Fortran user-defined programs 35can be directly used with C or Fortran user-defined programs
43dynamically linked (see \ref{dynamiclink}). . 36dynamically linked (see \ref{dynamiclink}). .
44 37
45An other way to add C or Fortran code to Scilab is by 38An other way to add C or Fortran code to Scilab is by
46building an interface program. The interface program can be written by 39building an interface program. The interface program can be written by
47the user following the examples given in the following directories 40the user following the examples given in the directories
48{\tt routines/examples/interface-tutorial} and {\tt routines/examples/interface-tour}. Examples of Matlab-like interfaces are given in the directory 41{\tt routines/examples/interface-*}. The simplest way to build an
49{\tt routines/examples/mexfiles}. 42interface program is to copy/paste one of the examples given there and to
43adapt the code to your problem.
44
45Examples of Matlab-like mexfunction interfaces are given in the
46directory {\tt routines/examples/mexfiles}.
50 47
51The interface program can also be generated by {\tt 48The interface program can also be generated by the tool {\tt
52intersci}. {\tt Intersci} builds the interface 49intersci}. {\tt Intersci} builds the interface
53program from a {\tt .desc} file which describes both the C or 50program from a {\tt .desc} file which describes both the C or
54Fortran program(s) to be used and the name and parameters of 51Fortran program(s) to be used and the name and parameters of
55the corresponding Scilab function(s). 52the corresponding Scilab function(s).
56 53
57Finally it is possible to add a permanent new primitive to Scilab
58by building an interface program as above and making a new executable
59code for Scilab. This is done by updating the {\tt fundef}
60file. In this case, the interface program should be given a specific
61name (e.g. the default name {\tt matus2}) and a number. The file
62{\tt default/fundef} should also be updated as done by {\tt intersci}.
63A new executable code is generated by typing ``make all''
64in the main Scilab directory.
65
66\section{Using dynamic link} 54\section{Using dynamic link}
67Several simple examples of dynamic link are given in the directory 55Several simple examples of dynamic link are given in the directory
68{\tt examples/link-examples}. In this section, we briefly describe 56{\tt examples/link-examples}. In this section, we briefly describe
@@ -72,9 +60,9 @@ how to call a dynamically linked program.
72The command {\tt link('path/pgm.o','pgm',flag)} 60The command {\tt link('path/pgm.o','pgm',flag)}
73links the compiled program {\tt pgm} to Scilab. 61links the compiled program {\tt pgm} to Scilab.
74Here {\tt pgm.o} is an object file located in the {\tt path} 62Here {\tt pgm.o} is an object file located in the {\tt path}
75directory and {\tt pgm} is an entry point (program name) in the file {\tt pgm.o} 63directory and {\tt pgm} is an entry point (program name) in the
76(An object file can have several entry points: to link them, use a vector of 64file {\tt pgm.o} (An object file can have several entry points: to link
77character strings such as \verb!['pgm1','pgm2']!). 65them, use a vector of character strings such as \verb!['pgm1','pgm2']!).
78 66
79{\tt flag} should be set to {\tt 'C'} for a C-coded program 67{\tt flag} should be set to {\tt 'C'} for a C-coded program
80and to {\tt 'F'} for a Fortran subroutine. ({\tt 'F'} is 68and to {\tt 'F'} for a Fortran subroutine. ({\tt 'F'} is
@@ -99,12 +87,10 @@ Link done
99 n = 87 n =
100 88
101 0. 89 0.
102 90 -->c_link('daxpy')
103-->c_link('daxpy')
104 ans = 91 ans =
105 92
106 T 93 T
107
108-->ulink(n) 94-->ulink(n)
109 95
110-->c_link('daxpy') 96-->c_link('daxpy')
@@ -113,7 +99,8 @@ Link done
113 F 99 F
114\end{verbatim} 100\end{verbatim}
115 101
116For more details, enter {\tt help link}. 102For more details, enter {\tt help link}. The {\tt link} primitive can load
103a set of object files and/or a static library and/or a dynamic library.
117 104
118\subsection{Calling a dynamically linked program} 105\subsection{Calling a dynamically linked program}
119 106
@@ -129,6 +116,11 @@ The calling sequence for {\tt daxpy} is as follows:
129\begin{verbatim} 116\begin{verbatim}
130 subroutine daxpy(n,a,x,incx,y,incy) 117 subroutine daxpy(n,a,x,incx,y,incy)
131\end{verbatim} 118\end{verbatim}
119The parameters of a Fortran program are pointers. The C code for the
120same function would be :
121\begin{verbatim}
122void daxpy(int *n,double *a,double *x,int *incx,double *y,int *incy)
123\end{verbatim}
132To call {\tt daxpy} from Scilab we must use a syntax as follows: 124To call {\tt daxpy} from Scilab we must use a syntax as follows:
133\begin{verbatim} 125\begin{verbatim}
134[y1,y2,y3,...]=call('daxpy', inputs description, ... 126[y1,y2,y3,...]=call('daxpy', inputs description, ...
@@ -144,7 +136,8 @@ where {\tt xi} is the Scilab variable (real vector or matrix) sent to
144{\tt daxpy}, 136{\tt daxpy},
145{\tt pi} is the position number of this variable in the calling 137{\tt pi} is the position number of this variable in the calling
146sequence of {\tt daxpy} and {\tt ti} is the type of {\tt xi} in {\tt daxpy} 138sequence of {\tt daxpy} and {\tt ti} is the type of {\tt xi} in {\tt daxpy}
147({\tt t='i' t='r' t='d'} stands for integer, real or double). 139({\tt t='i' t='r' t='d' t='c'} stands for integer, real, double, char
140 respectively).
148 141
149\noindent 142\noindent
150{\tt outputs description} is a set of parameters 143{\tt outputs description} is a set of parameters
@@ -153,9 +146,9 @@ sequence of {\tt daxpy} and {\tt ti} is the type of {\tt xi} in {\tt daxpy}
153 146
154\noindent 147\noindent
155which describes each output variable. {\tt [ri,ci]} is the 148which describes each output variable. {\tt [ri,ci]} is the
1562 x 1 integer vector giving the number of rows and columns of the 1491 x 2 integer vector giving the number of rows and columns of the
157ith output variable {\tt yi}. {\tt pi} and {\tt ti} are as for 150ith output variable {\tt yi}. The position, {\tt pi}, and the type, {\tt ti},
158input variables (they can be omitted if a variable is both input and 151are as for input variables (they can be omitted if a variable is both input and
159output). 152output).
160 153
161We see that the arguments of {\tt call} divided into four groups. 154We see that the arguments of {\tt call} divided into four groups.
@@ -163,12 +156,12 @@ The first argument {\tt 'daxpy'} is the name of the called subroutine.
163The argument {\tt 'out'} divides the remaining arguments into two 156The argument {\tt 'out'} divides the remaining arguments into two
164groups. The group of arguments between {\tt 'daxpy'} and {\tt 'out'} 157groups. The group of arguments between {\tt 'daxpy'} and {\tt 'out'}
165is the list of input arguments, their positions in the call to {\tt daxpy}, 158is the list of input arguments, their positions in the call to {\tt daxpy},
166and their data type. The group of arguments to the right of {\tt 'out'} 159and their data type. The group of arguments at the right of {\tt 'out'}
167are the dimensions of the output variables, their positions in the call 160are the dimensions of the output variables, their positions in the calling
168to {\tt daxpy}, and their data type. 161sequence of {\tt daxpy}, and their data type.
169The possible data types are real, integer, and double precision which 162The possible data types are real, integer, double and character which
170are indicated, respectively, by the strings {\tt 'r'}, {\tt 'i'}, and 163are indicated, respectively, by the strings {\tt 'r'}, {\tt 'i'}, {\tt 'd'}
171{\tt 'd'}. 164and {\tt 'c'}.
172Here we calculate {\tt y=y+a*x} by a call to {\tt daxpy} (assuming 165Here we calculate {\tt y=y+a*x} by a call to {\tt daxpy} (assuming
173that the {\tt link} command has been done). 166that the {\tt link} command has been done).
174We have six input variables 167We have six input variables
@@ -180,13 +173,11 @@ at position {\tt p1=5}. To simplify, we assume here that {\tt x} and
180\begin{verbatim} 173\begin{verbatim}
181-->a=3; 174-->a=3;
182 175
183-->x=[1,2,3,4]; 176-->x=[1,2,3,4];y=[1,1,1,1];
184
185-->y=[1,1,1,1];
186 177
187-->incx=1;incy=1; 178-->incx=1;incy=1;
188 179
189-->n=size(x,'*'); 180-->n=length(x); //n=4
190 181
191-->y=call('daxpy',... 182-->y=call('daxpy',...
192 n,1,'i',... 183 n,1,'i',...
@@ -201,7 +192,6 @@ at position {\tt p1=5}. To simplify, we assume here that {\tt x} and
201 y = 192 y =
202 193
203! 4. 7. 10. 13. ! 194! 4. 7. 10. 13. !
204
205\end{verbatim} 195\end{verbatim}
206(Since {\tt y} is both input and output parameter, we could also use 196(Since {\tt y} is both input and output parameter, we could also use
207the simplified syntax 197the simplified syntax
@@ -240,19 +230,44 @@ Link done
240 230
241The routines which are linked to Scilab can also access internal 231The routines which are linked to Scilab can also access internal
242Scilab variables: see the examples in given in the {\tt examples/links} 232Scilab variables: see the examples in given in the {\tt examples/links}
243directory. 233directory.
234
235\subsection{Building a dynamic library}
236The simple link of an object file as illustrated above may not work on some
237platforms. In this case, it is neccesary to build a (possibly dynamic) library
238containing a set of programs and to link the library with Scilab.
239Examples are given the directory {\tt SCIDIR/example/link-examples-so}
240which are built to run in both a Linux/Unix (.so or .sl library) or
241Windows environment (.dll library). The library is constructed by a specific
242Scilab function {\verb!ilib_for_link!} (which make use of libtool for Unix/
243Linux libraries).
244Enter \verb!-->exec ext1c.sce! at the Scilab prompt, in this directory to
245see the simplest C example. The script file {\tt ext1c.sce} contains a call
246to {\verb!ilib_for_link!} with appropriate parameters (files to be compiled,
247others libraries required, etc). The library is built using the environment
248parameters known by Scilab (compiler, linker etc). In addition a Scilab script
249with generic name {\tt loader.sce} is created in the current directory.
250This script contains contains the code necessary to link the library with
251Scilab. Typically, it is a call to the {\tt link} primitive, with an
252appropriate entry point (usually the name of the linked function).
253Note that the script file performs two tasks: building of the library
254and link of the library with the running Scilab. The first task is
255generally performed once while the second should be made in every Scilab
256session which needs linking the library.
244 257
245\section{Interface programs} 258\section{Interface programs}
246 259
247\subsection{Building an interface program} 260\subsection{Building an interface program}
248Examples of interface programs are given in the directory 261Many examples of interface programs are given in the
249{\tt examples/interface-tutorial} and {\tt examples/interface-tour}. 262directories/subdirectories {\tt SCIDIR/examples/interface-*}.
250 263
251The interface programs use a set of C or 264The interface programs use a set of C or Fortran routines which
252Fortran routines which should be used to build the interface program. 265are given in {\tt SCIDIR/routines/stack-c.h} and known by Scilab
253The simplest way to learn how to build an interface program is to 266when this file is included in the interface program.
254customize the previous skeletons files and to look at the examples 267
255provided in this directory. 268The simplest way to learn how to build an interface program is to
269look at the examples provided in the directory {\tt interface-tutorial}.
270
256Note that a unique interface program can be used to interface an 271Note that a unique interface program can be used to interface an
257arbitrary (but less that $99$) number of functions. 272arbitrary (but less that $99$) number of functions.
258 273
@@ -303,8 +318,14 @@ should be sent to the C function \verb!matmul! and the matrix
303\verb!C! should be created, filled, and sent back to Scilab. 318\verb!C! should be created, filled, and sent back to Scilab.
304 319
305To create the Scilab function \verb!matmul!, we have to write 320To create the Scilab function \verb!matmul!, we have to write
306the following C gateway function called 321a gateway function (an interface function).
307\verb!intmatmul!. See the file \newline 322A gateway function is a C function which must include the header file
323{\tt stack-c.h}. Fortran gatways include the file {\tt stack.h}.
324These files are located in the SCIDIR/routines directory.
325
326The following C gateway function called
327\verb!intmatmul! is an example of interface for the matrix multiplication
328program {\tt matmul}. See the file \newline
308\verb!SCIDIR/examples/interface-tutorial/intmatmul.c!. 329\verb!SCIDIR/examples/interface-tutorial/intmatmul.c!.
309 330
310\scriptsize 331\scriptsize
@@ -314,8 +335,8 @@ the following C gateway function called
314int intmatmul(fname) 335int intmatmul(fname)
315 char *fname; 336 char *fname;
316{ 337{
317 static int l1, m1, n1, l2, m2, n2, l3; 338 int l1, m1, n1, l2, m2, n2, l3;
318 static int minlhs=1, maxlhs=1, minrhs=2, maxrhs=2; 339 int minlhs=1, maxlhs=1, minrhs=2, maxrhs=2;
319 340
320 /* Check number of inputs (Rhs=2) and outputs (Lhs=1) */ 341 /* Check number of inputs (Rhs=2) and outputs (Lhs=1) */
321 CheckRhs(minrhs,maxrhs) ; CheckLhs(minlhs,maxlhs) ; 342 CheckRhs(minrhs,maxrhs) ; CheckLhs(minlhs,maxlhs) ;
@@ -369,7 +390,7 @@ The function \verb!CheckRhs! just compares the C variable \verb!Rhs!
369\noindent 390\noindent
370The next step is to deal with the Scilab variables \verb!A!, \verb!B! 391The next step is to deal with the Scilab variables \verb!A!, \verb!B!
371and \verb!C!. In a gateway function, all the Scilab variables 392and \verb!C!. In a gateway function, all the Scilab variables
372are referred to as numbers. Here, the Scilab matrices 393are referred to as integer numbers. Here, the Scilab matrices
373\verb!A!, \verb!B! and \verb!C! are 394\verb!A!, \verb!B! and \verb!C! are
374respectively numbered \verb!1!, \verb!2! and \verb!3!. 395respectively numbered \verb!1!, \verb!2! and \verb!3!.
375Each input variable of the newly created Scilab function 396Each input variable of the newly created Scilab function
@@ -588,8 +609,15 @@ execute the script \verb!loader.sce!.
588\subsection{Functions used for building an interface} 609\subsection{Functions used for building an interface}
589The functions used to build an interface are Fortran subroutines when 610The functions used to build an interface are Fortran subroutines when
590the interface is written in Fortran and are coded as C macros 611the interface is written in Fortran and are coded as C macros
591(defined in {\tt stack-c.h} ) 612when the interface is coded in C.
592when the interface is coded in C. The main functions are as follows: 613An interface (gateway) routine is a standard C function or Fortran
614program which include the file {\tt SCIDIR/routines/stack-c.h}
615(C coded gateway) or {\tt SCIDIR/routines/stack.h} (Fortran coded gateway).
616
617The C functions which can be used in an interface program are available
618as soon as {\tt SCIDIR/routines/stack-c.h} is included in the source code.
619
620The main functions are the following:
593 621
594\begin{itemize} 622\begin{itemize}
595\item{ 623\item{
@@ -706,19 +734,348 @@ The best way to build an interface is to copy one of the examples
706given there and to adapt the code to particular needs. 734given there and to adapt the code to particular needs.
707 735
708 736
709\subsection{The {\tt addinter} command} 737\section{Argument functions}
710Once the interface program is written, it must be compiled to produce 738Some built-in nonlinear solvers, such as {\tt ode} or {\tt optim}, require a
711an object file. It is then linked to Scilab by the addinter command. 739specific function as argument. For instance in the Scilab command
740{\tt ode(x0,t0,t,fydot)}, {\tt fydot} is the specific argument function
741for the {\tt ode} primitive.
742This function can be a either Scilab function or an external
743function written in C or Fortran.
744In both cases, the argument function must obey a specific
745syntax. In the following we will consider, as running example, using
746the {\tt ode} primitive with a rhs function written in Fortran. The
747same steps should be followed for all primitives which require
748a function as argument.
749
750If the argument function is written in C or Fortran, there
751are two ways to call it:
752\begin{itemize}
753\item -Use dynamic link
754\begin{verbatim}
755-->link('myfydot.o','myfydot')
756//or -->link('myfydot.o','myfydot','C')
757-->ode(x0,t0,t,'myfydot')
758\end{verbatim}
759\item -Use the {\tt Ex-ode.f} interface in the {\tt routines/default}
760directory (and {\tt make all} in Scilab directory).
761The call to the {\tt ode} function is as above:
762\begin{verbatim}
763-->ode(x0,t0,t,'myfydot')
764\end{verbatim}
765\end{itemize}
766In this latter case, to add a new function, two files should be updated:
767\begin{itemize}
768\item The {\tt Flist} file: Flist is list of entry points. Just add the
769name of your function at in the appropriate list of functions.
770\begin{verbatim}
771ode_list= ... myfydot
772\end{verbatim}
773\item The {\tt Ex-ode.f} (or {\tt Ex-ode-more.f}) file: this file contains the
774source code for argument functions. Add your function here.
775\end{itemize}
776
777Many exemples are provided in the {\tt default} directory.
778More complex examples are also given. For instance it is shown
779how to use Scilab variables as optional parameters of {\tt fydot}.
712 780
713The syntax of addinter is the following: 781\section{Mexfiles}
782The directories under \verb!SCIDIR/examples/mexfiles! contain
783some examples of Matlab mexfiles which can be used as interfaces
784in the Scilab environment. The Scilab \verb!mexlib! library emulates
785the most commonly used Matlab \verb!mxfunctions! such as
786\verb!mxGetM!, \verb!mxGetPr!, \verb!mxGetIr! etc. Not all the
787\verb!mxfunctions! are available but standard mexfiles which make use
788of matrices (possibly sparse), structs, character strings
789and n-dimensional arrays can be used without any modification
790in the Scilab environment. If the source program is already compiled
791and the mexfile given as a dynamic library, it is possible to link
792the library with Scilab (examples are provided for Linux (.glnx extension)
793or Windows (.dll extension)).
794
795\section{Complements}
796\subsection{Examining the data, function {\tt GetData}}
797The functions {\tt GetRhsVar} and {\tt CreateVar}
798described above for building an interface program can be used for
799most programs involving matrices. Many other functions can be used
800for handling Scilab more complex data such as lists. See the examples
801in the directories examples/interfaces.
802It is also possible to define new objects from scratch within an interface.
803Let us first describe how to scan the Scilab objects. This can be done by the
804function {\tt GetData}.
805Consider the following simple interface program:
806\begin{verbatim}
807#include "stack-c.h"
808void intscan()
809{
810 int *header; double *data;
811 header = GetData(1);
812 printf("%i %i %i %i\n", header[0], header[1], header[2], header[3]);
813 data = (double *) &header[4];
814 printf("%f %f %f\n", data[0]);
815}
816\end{verbatim}
817This interface can be built by the following Scilab script, \verb!scan.sce!:
818\begin{verbatim}
819ilib_name = 'libintscan';
820files = ['intscan.o'];
821libs = [];
822table = ['scan', 'intscan'];
823ilib_build(ilib_name,table,files,libs);
824\end{verbatim}
825After entering \verb!-->exec scan.sce! at Scilab prompt, a file \verb!loader.sce! is made:
826\begin{verbatim}
827libintscan_path=get_file_path('loader.sce');
828functions=['scan';];
829addinter(libintscan_path+'/libintscan.so','libintscan',functions);
830\end{verbatim}
831Entering \verb!-->exec loader.sce! allows to call the new \verb!scan! function.
832Now we can see the output of \verb!scan(A)! for, e.g., \verb!A=[4,2,3]!.
833We see that the Scilab variable \verb!A! is represented internally by
834a set of 4 integers (1,1,3,0) (the ``header'') followed by 3
835doubles (4,2,3) (the ``data''). The header is made of the following:
836type (1 stands for ``numeric matrix''), number of rows (1 since \verb!A!
837is a row vector), number of columns (3 since \verb!A! has three
838columns), complex type (0 since \verb!A! is real). The data contains
839the entries of \verb!A!. All entries are considered (and stored) as double.
840Cleary, the function can be used to examine how Scilab variables are stored
841internally. For instance if \verb!B=int32(A)! we see that \verb!B! is stored
842with the header (8,1,3,4) and the int data (2,3,4). All integer matrix have
843the type 8, and int32 receive the flag 4.
844
845The following program shows how a matrix of strings is represented.
846\begin{verbatim}
847#include "stack-c.h"
848void intscan()
849{
850 int *header;
851 int k,length,start,number;
852 header = (int *) GetData(1);
853 /* header = [10,Mrows,Ncols,0] ... */
854 sciprint("string-type= %i, nrows= %i, ncols=%i, (reserved=) %i \n",
855 header[0],header[1],header[2],header[3]);
856 /* ..[1, 1+length(entry 1),., 1+ .. +length(entry M*N) ].. */
857 number=header[1]*header[2];
858 start=5+number;
859 /* codes entry 1, ..., codes entry M*N */
860 for (k=5; k<5+number; k++) {
861 length=header[k]-header[k-1];
862 sciprint("string %i has length %i\n", k-4, length);
863 sciprint("Code: first char =%i last char = %i\n",header[start],
864 header[start+length-1]);
865 start=start+length;
866 }
867}
868\end{verbatim}
869We see here that string matrices are internally represented by integers.
870When a string matrix is passed to an interface and the
871string matrix is processed by \verb!GetRhsVar(n,'c',&M,&N,&l)!
872then the strings are transformed into C chars.
873They can be obtained by the following piece of interface:
874\begin{verbatim}
875#include "stack-c.h"
876void intscan()
877{
878 int M,N,l; char *str;
879 GetRhsVar(1, "c", &M, &N, &l);
880 str = (char *) cstk(l);
881}
882\end{verbatim}
714 883
715{\tt addinter([`interface.o', 'userfiles.o'],'entrypt',['scifcts'])} 884\subsection{Creating new data types, function {\tt CreateData}}
716 885
717Here {\tt interface.o} is the object file of the interface, 886Consider now the interface program:
718{\tt userfiles.o} is the set of user's routines to be linked, 887\begin{verbatim}
719{\tt entrypt} is the entry point of the interface routine and 888#include "stack-c.h"
720{'scifcts'} is the set of Scilab functions to be interfaced. 889void intmy133()
890{
891 int *header;
892 CreateData(1, 5*sizeof(int));
893 header = GetData(1);
894 header[0]=133; header[1]=1; header[2]=3; header[3]=0;
895 header[4]=35;
896 LhsVar(1)=1;
897}
898\end{verbatim}
899This interface can be built by the following Scilab script, \verb!my133.sce!:
900\begin{verbatim}
901ilib_name = 'lib133';
902files = ['intmy133.o'];
903libs = [];
904table = ['my133', 'intmy133'];
905ilib_build(ilib_name,table,files,libs);
906\end{verbatim}
907After entering \verb!-->exec my133.sce! at Scilab prompt,
908a file \verb!loader.sce! is made, in the current directory and the new scilab
909function \verb!my133! is available after entering \verb!-->exec loader.sce!.
910Let us call this function. We get:
911\begin{verbatim}
912-->X=my133()
913 X =
914
915Undefined display for this data type
916-->type(X)
917 ans =
918
919 133.
920\end{verbatim}
921A new variable has been created. Scilab knows its type \verb!133! which is
922the first integer in the header, but Scilab is unable to display this variable.
923We can attach a generic name to the type 133, by doing the following:
924\begin{verbatim}
925-->typename('mytype', 133)
926\end{verbatim}
927The list of current names and types is obtained by the command
928\verb![names,types]=typname()! . The command \verb!typeof(X)! now returns
929\verb!mytype!.
930Now we can overload a function to display \verb!X!.
931\begin{verbatim}
932-->function %mytype_p(X)
933-->disp('Cannot display this variable!')
934-->endfunction
935
936-->X
937 X =
938
939Cannot display this variable!
940\end{verbatim}
941Indeed, at this stage we have created a new type of variable, \verb!133! with
942name {\tt mytype}. To really display the variable, we need to write a new
943interface function.
944Let us consider the following:
945\begin{verbatim}
946#include "stack-c.h"
947void intdisp133()
948{
949 int *header;
950 header = GetData(1);
951 header[0]=8;
952 LhsVar(1)=1;
953}
954\end{verbatim}
955This function does nothing, except changing \verb!header[0]! from 133 to
9568.
957We can build a library with the two functions \verb!my133! and \verb!disp133!
958with the scilab script:
959\begin{verbatim}
960ilib_name = 'lib133';
961files = ['intmy133.o', 'intdisp133.o'];
962libs = [];
963table = ['my133', 'intmy133';
964 'disp133' ,'intdisp133'];
965ilib_build(ilib_name,table,files,libs);
966\end{verbatim}
721 967
968We can redefined the display function for variables tagged \verb!"mytype"!
969by \verb!typename!.
970\begin{verbatim}
971-->function %mytype_p(X)
972-->disp(disp133(X))
973-->endfunction
974
975-->X
976 X =
977
97835
979\end{verbatim}
980When \verb!X! is typed at the scilab prompt, the function \verb!%mytype!
981is searched to display \verb!X!, since \verb!X! is a variable of type 133
982and such variables have the generic name "mytype", set by the command
983\verb!typename('mytype',133)!. The function \verb!disp133! transforms the
984variable X into a standard 1 x 1 integer matrix containing the constant 35.
985(Note that only the type needs to be set).
986
987\subsection{Values or references}
988By default, the arguments given to the interface are passed ``by value''.
989This means that, in the interface program, one is working with a copy
990of the Scilab data. Consider for instance the following gateway function:
991\begin{verbatim}
992#include "stack-c.h"
993void inttstfct()
994{ int m1,n1,l1;
995 GetRhsVar(1, "d", &m1, &n1, &l1);
996 stk(l1)[0] = 1;
997 LhsVar(1) = 1;
998}
999\end{verbatim}
1000for the Scilab function {\tt X=tstfct(A)}. We assume that the variable \verb!A!
1001passed to \verb!tstfct! is a standard real matrix.
1002Note that we could use the following gateway which performs the same job.
1003\begin{verbatim}
1004#include "stack-c.h"
1005void inttstfct()
1006{ int *header; double *data;
1007 header = (int *) GetData(1);
1008 data = (double *) &header[4];
1009 data[0] = 1;
1010 LhsVar(1) = 1;
1011}
1012\end{verbatim}
1013This function is installed into Scilab by executing the script
1014\begin{verbatim}
1015ilib_name = 'libinttstfct';
1016files = ['inttstfct.o'];
1017libs = [];
1018table = ['tstfct', 'inttstfct'];
1019ilib_build(ilib_name,table,files,libs);
1020\end{verbatim}
1021and executing the newly created script \verb!loader.sce!.
1022
1023Assume also that \verb!A! is the 2 x 2 matrix \verb!A=zeros(2,2)!,
1024and consider the Scilab command \verb!-->B=tstfct(A)!. In the interface
1025program, before its assignment, \verb!stk(l1)[0]! is equal to 0, i.e. the first
1026entry of \verb!A!, {\tt A(1,1)}.
1027The output {\tt B} will be, as expected, the Scilab matrix \verb![1 0;0 0]!.
1028But the Scilab variable {\tt A} will not be modified. This behavior is similar
1029with the usual Scilab functions: the input parameters of the function are
1030not modified when the function is called.
1031It is however possible to pass the parameters by reference. This can be useful
1032if the interfaced program do not alter the input data (the data can be used
1033in read-only mode).
1034Let us enter the command \verb!-->funptr tstfct!. We get:
1035\begin{verbatim}
1036-->funptr tstfct
1037 ans =
1038
1039 50101.
1040\end{verbatim}
1041which means: the function \verb!tstfct! has number \verb!01! in interface
1042number \verb!501!.
1043It is possible to convert the gateway function into a gateway in which the
1044variables are passed by reference. This is done as follows
1045by the function \verb!intppty!.
1046\begin{verbatim}
1047-->intppty(501) // adding gateway 501 to the list.
1048
1049-->intppty()
1050 ans =
1051
1052! 6. 13. 16. 19. 21. 23. 41. 42. 501. !
1053\end{verbatim}
1054Note that if several Scilab functions are built together in the same
1055inerface they will all receive input parameters as reference.
1056The behavior of \verb!tstfct! is changed. Its argument is modified when
1057\verb!tstfct! is called:
1058\begin{verbatim}
1059-->A
1060 A =
1061
1062! 0. 0. !
1063! 0. 0. !
1064-->tstfct(A)
1065 ans =
1066
1067! 1. 0. !
1068! 0. 0. !
1069-->A
1070 A =
1071
1072! 1. 0. !
1073! 0. 0. !
1074\end{verbatim}
1075Finally, we note that the function {\tt GetRawData} gives the
1076internal representation of the reference variable and {\tt GetData}
1077gives the internal representation of the value variable pointed to
1078by the reference.
722\section{Intersci} 1079\section{Intersci}
723The directory \verb!SCIDIR/examples/intersci-examples-so! contains 1080The directory \verb!SCIDIR/examples/intersci-examples-so! contains
724several examples for using \verb!intersci! which is a tool for 1081several examples for using \verb!intersci! which is a tool for
@@ -774,7 +1131,6 @@ The file \verb!ex01fi.c! is the C gateway function needed for interfacing
774\scriptsize 1131\scriptsize
775\begin{verbatim} 1132\begin{verbatim}
776#include "stack-c.h" 1133#include "stack-c.h"
777
778int intsext1c(fname) 1134int intsext1c(fname)
779 char *fname; 1135 char *fname;
780{ 1136{
@@ -831,228 +1187,7 @@ To use \verb!intersci! one has to construct a \verb!.desc! file.
831The keywords which describe the Scilab function and the function 1187The keywords which describe the Scilab function and the function
832to be called can be found in the examples given. 1188to be called can be found in the examples given.
833 1189
834\section{Argument functions}
835Some built-in nonlinear solvers, such as {\tt ode} or {\tt optim}, require a
836specific function as argument. For instance in the Scilab command
837{\tt ode(x0,t0,t,fydot)}, {\tt fydot} is the specific argument function
838for the {\tt ode} primitive.
839This function can be a either Scilab function or an external
840function written in C or Fortran.
841In both cases, the argument function must obey a specific
842syntax. In the following we will consider, as running example, using
843the {\tt ode} primitive with a rhs function written in Fortran. The
844same steps should be followed for all primitives which require
845a function as argument.
846
847If the argument function is written in C or Fortran, there
848are two ways to call it:
849\begin{itemize}
850\item -Use dynamic link
851\begin{verbatim}
852-->link('myfydot.o','myfydot')
853//or -->link('myfydot.o','myfydot','C')
854-->ode(x0,t0,t,'myfydot')
855\end{verbatim}
856\item -Use the {\tt Ex-ode.f} interface in the {\tt routines/default}
857directory (and {\tt make all} in Scilab directory).
858The call to the {\tt ode} function is as above:
859\begin{verbatim}
860-->ode(x0,t0,t,'myfydot')
861\end{verbatim}
862\end{itemize}
863In this latter case, to add a new function, two files should be updated:
864\begin{itemize}
865\item The {\tt Flist} file: Flist is list of entry points. Just add the
866name of your function at in the appropriate list of functions.
867\begin{verbatim}
868ode_list= ... myfydot
869\end{verbatim}
870\item The {\tt Ex-ode.f} (or {\tt Ex-ode-more.f}) file: this file contains the
871source code for argument functions. Add your function here.
872\end{itemize}
873
874Many exemples are provided in the {\tt default} directory.
875More complex examples are also given. For instance it is shown
876how to use Scilab variables as optional parameters of {\tt fydot}.
877\section{Mexfiles}
878The directories under \verb!SCIDIR/examples/mexfiles! contain
879some examples of Matlab mexfiles which can be used as interfaces
880in the Scilab environment. The Scilab \verb!mexlib! library emulates
881the most commonly used Matlab \verb!mxfunctions! such as
882\verb!mxGetM!, \verb!mxGetPr!, \verb!mxGetIr! etc. Not all the
883\verb!mxfunctions! are available but standard mexfiles which make use
884of matrices (possibly sparse), character strings and n-dimensional arrays
885can be used without any modification in the Scilab environment.
886
887\section{Maple to Scilab Interface}
888To combine symbolic computation of the computer algebra system Maple with the
889numerical facilities
890of Scilab, Maple objects can be transformed into Scilab functions. To assure
891efficient numerical evaluation this is done through numerical evaluation in
892Fortran. The whole process is done by a Maple procedure called
893\verb/maple2scilab/.
894\section{Maple2scilab}
895\index{maple2scilab@{\tt maple2scilab}}
896The procedure \verb!maple2scilab! converts a Maple object,
897either a scalar function or a matrix into a Fortran subroutine
898and writes the associated Scilab function. The code of \verb!maple2scilab!
899is in the directory \verb!SCIDIR/maple!.
900
901The calling sequence of \verb!maple2scilab! is as follows:\\
902\verb!maple2scilab(function-name,object,args)!
903\begin{itemize}
904\item
905The first argument, \verb!function-name! is a name indicating the
906function-name in Scilab.
907\item
908The second argument \verb!object! is the Maple name of the expression
909to be transferred to Scilab.
910\item
911The third argument is a list of arguments containing the formal parameters of
912the Maple-object \verb!object!.
913\end{itemize}
914When \verb!maple2scilab! is invoked in Maple, two files are generated,
915one which contains the Fortran code and another which contains the
916associated Scilab function. Aside their existence, the user has not to
917know about their contents.
918
919The Fortran routine which is generated has the following calling sequence:\\
920{\tt <Scilab-name>(x1,x2,\ldots,xn,matrix)} \\
921and this subroutine computes matrix(i,j) as a function of
922the arguments {\tt x1,x2,\ldots,xn}.
923Each argument can be a Maple scalar or array which should be
924in the argument list.
925The Fortran subroutine is put into a file named {\tt <Scilab-name>.f}, the
926Scilab-function into a file named {\tt <Scilab-name>.sci}.
927For numerical evaluation in Scilab the user has to compile the Fortran
928subroutine, to link it with Scilab (e.g. Menu-bar option '\verb!link!')
929and to load the associated function (Menu-bar option '\verb!getf!').
930Information about \verb!link! operation is given in Scilab's manual:
931Fortran routines can be incorporated into Scilab by dynamic
932link or through the \verb!Ex-fort.f! file in the \verb!default! directory.
933 Of course, this two-step procedure can be automatized using a shell-script
934(or using \verb!unix! in Scilab).
935Maple2scilab uses the ``Macrofort'' library which is in the share
936library of Maple.
937\subsection{Simple Scalar Example}
938\paragraph{Maple-Session}
939\begin{verbatim}
940> read(`maple2scilab.maple`):
941> f:=b+a*sin(x);
942
943 f := b + a sin(x)
944 1190
945> maple2scilab('f_m',f,[x,a,b]);
946\end{verbatim}
947Here the Maple variable \verb!f! is a scalar expression but it could be also
948a Maple vector or matrix.
949\verb/ 'f_m'/ will be the name of \verb!f! in Scilab
950(note that the Scilab name is restricted to contain at most 6 characters).
951The procedure \verb/maple2scilab/ creates two files: \verb/f_m.f/
952and \verb/f_m.sci/ in the directory where Maple is started.
953To specify another directory just define in Maple the path :
954\verb/rpath:=`//\verb/work//` ; then all files are written in
955the sub-directory \verb/work/.
956The file \verb!f_m.f! contains the source code of a stand alone Fortran
957routine which is dynamically linked to Scilab by the function \verb!f_m! in
958defined in the file \verb!f_m.sci!.
959
960\paragraph{Scilab Session}
961\begin{verbatim}
962-->unix('make f_m.o');
963
964-->link('f_m.o','f_m');
965
966linking _f_m_ defined in f_m.o
967
968-->getf('f_m.sci','c')
969
970-->f_m(%pi,1,2)
971 ans =
972
973 2.
974\end{verbatim}
975
976\subsection{Matrix Example}
977This is an example of transferring a Maple matrix into Scilab.
978\paragraph{Maple Session}
979\begin{verbatim}
980> with(linalg):read(`maple2scilab.maple`):
981
982> x:=vector(2):par:=vector(2):
983
984> mat:=matrix(2,2,[x[1]^2+par[1],x[1]*x[2],par[2],x[2]]);
985
986 [ 2 ]
987 [ x[1] + par[1] x[1] x[2] ]
988 mat := [ ]
989 [ par[2] x[2] ]
990
991> maple2scilab('mat',mat,[x,par]);
992
993\end{verbatim}
994
995\paragraph{Scilab Session}
996\begin{verbatim}
997-->unix('make mat.o');
998
999-->link('mat.o','mat')
1000
1001linking _mat_ defined in mat.o
1002
1003-->getf('mat.sci','c')
1004
1005-->par=[50;60];x=[1;2];
1006
1007-->mat(x,par)
1008 ans =
1009
1010! 51. 2. !
1011! 60. 2. !
1012
1013\end{verbatim}
1014
1015{\small
1016\paragraph{Generated code}
1017Below is the code (Fortran subroutines and Scilab functions) which is
1018automatically generated by {\tt maple2scilab} in the two preceding examples.
1019\paragraph{Fortran routines}
1020\begin{verbatim}
1021c
1022c SUBROUTINE f_m
1023c
1024 subroutine f_m(x,a,b,fmat)
1025 doubleprecision x,a,b
1026 implicit doubleprecision (t)
1027 doubleprecision fmat(1,1)
1028 fmat(1,1) = b+a*sin(x)
1029 end
1030\end{verbatim}
1031\begin{verbatim}
1032c
1033c SUBROUTINE mat
1034c
1035 subroutine mat(x,par,fmat)
1036 doubleprecision x,par(2)
1037 implicit doubleprecision (t)
1038 doubleprecision fmat(2,2)
1039 t2 = x(1)**2
1040 fmat(2,2) = x(2)
1041 fmat(2,1) = par(2)
1042 fmat(1,2) = x(1)*x(2)
1043 fmat(1,1) = t2+par(1)
1044 end
1045\end{verbatim}
1046\paragraph{Scilab functions}
1047\begin{verbatim}
1048function [var]=f_m(x,a,b)
1049var=call('f_m',x,1,'d',a,2,'d',b,3,'d','out',[1,1],4,'d')
1050\end{verbatim}
1051\begin{verbatim}
1052function [var]=fmat(x,par)
1053var=call('fmat',x,1,'d',par,2,'d','out',[2,2],3,'d')
1054\end{verbatim}
1055}
1056%\end{document} 1191%\end{document}
1057 1192
1058 1193