diff options
author | Francois Delebecque <Francois.Delebecque@inria.fr> | 2004-09-23 14:13:37 +0000 |
---|---|---|
committer | Francois Delebecque <Francois.Delebecque@inria.fr> | 2004-09-23 14:13:37 +0000 |
commit | 58189be3678e83c70631afb153b283ba9b980cbd (patch) | |
tree | 64cce2949cc39c6b36c89d2851fa73b5c980f7d5 /scilab_doc | |
parent | a0d9d653d9b36ed1c84402ea7d0a60dea9424622 (diff) | |
download | scilab-58189be3678e83c70631afb153b283ba9b980cbd.zip scilab-58189be3678e83c70631afb153b283ba9b980cbd.tar.gz |
new
Diffstat (limited to 'scilab_doc')
-rwxr-xr-x | scilab_doc/intro/chap6.tex | 723 |
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 | ||
14 | Scilab can be easily interfaced with Fortran or C programs. | 3 | Scilab can be easily interfaced with Fortran or C programs. |
15 | This is useful to have faster code or to use specific numerical | 4 | This is useful to have faster code or to use specific numerical |
@@ -38,31 +27,30 @@ and then to interactively call | |||
38 | the linked routine by {\tt call}\index{call@{\tt call}} primitive | 27 | the linked routine by {\tt call}\index{call@{\tt call}} primitive |
39 | which transmits Scilab variables (matrices or strings) to the linked program | 28 | which transmits Scilab variables (matrices or strings) to the linked program |
40 | and transforms back the output parameters into Scilab variables. | 29 | and transforms back the output parameters into Scilab variables. |
30 | Note that all the parameters of the routine called by the {\tt call} | ||
31 | primitive must be pointers. In particular Fortran routines can be called | ||
32 | using the {\tt call} primitive. | ||
33 | |||
41 | Note that ode/dae solvers and non linear optimization primitives | 34 | Note that ode/dae solvers and non linear optimization primitives |
42 | can be directly used with C or Fortran user-defined programs | 35 | can be directly used with C or Fortran user-defined programs |
43 | dynamically linked (see \ref{dynamiclink}). . | 36 | dynamically linked (see \ref{dynamiclink}). . |
44 | 37 | ||
45 | An other way to add C or Fortran code to Scilab is by | 38 | An other way to add C or Fortran code to Scilab is by |
46 | building an interface program. The interface program can be written by | 39 | building an interface program. The interface program can be written by |
47 | the user following the examples given in the following directories | 40 | the 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}. | 42 | interface program is to copy/paste one of the examples given there and to |
43 | adapt the code to your problem. | ||
44 | |||
45 | Examples of Matlab-like mexfunction interfaces are given in the | ||
46 | directory {\tt routines/examples/mexfiles}. | ||
50 | 47 | ||
51 | The interface program can also be generated by {\tt | 48 | The interface program can also be generated by the tool {\tt |
52 | intersci}. {\tt Intersci} builds the interface | 49 | intersci}. {\tt Intersci} builds the interface |
53 | program from a {\tt .desc} file which describes both the C or | 50 | program from a {\tt .desc} file which describes both the C or |
54 | Fortran program(s) to be used and the name and parameters of | 51 | Fortran program(s) to be used and the name and parameters of |
55 | the corresponding Scilab function(s). | 52 | the corresponding Scilab function(s). |
56 | 53 | ||
57 | Finally it is possible to add a permanent new primitive to Scilab | ||
58 | by building an interface program as above and making a new executable | ||
59 | code for Scilab. This is done by updating the {\tt fundef} | ||
60 | file. In this case, the interface program should be given a specific | ||
61 | name (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}. | ||
63 | A new executable code is generated by typing ``make all'' | ||
64 | in the main Scilab directory. | ||
65 | |||
66 | \section{Using dynamic link} | 54 | \section{Using dynamic link} |
67 | Several simple examples of dynamic link are given in the directory | 55 | Several 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. | |||
72 | The command {\tt link('path/pgm.o','pgm',flag)} | 60 | The command {\tt link('path/pgm.o','pgm',flag)} |
73 | links the compiled program {\tt pgm} to Scilab. | 61 | links the compiled program {\tt pgm} to Scilab. |
74 | Here {\tt pgm.o} is an object file located in the {\tt path} | 62 | Here {\tt pgm.o} is an object file located in the {\tt path} |
75 | directory and {\tt pgm} is an entry point (program name) in the file {\tt pgm.o} | 63 | directory 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 | 64 | file {\tt pgm.o} (An object file can have several entry points: to link |
77 | character strings such as \verb!['pgm1','pgm2']!). | 65 | them, 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 |
80 | and to {\tt 'F'} for a Fortran subroutine. ({\tt 'F'} is | 68 | and 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 | ||
116 | For more details, enter {\tt help link}. | 102 | For more details, enter {\tt help link}. The {\tt link} primitive can load |
103 | a 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} |
119 | The parameters of a Fortran program are pointers. The C code for the | ||
120 | same function would be : | ||
121 | \begin{verbatim} | ||
122 | void daxpy(int *n,double *a,double *x,int *incx,double *y,int *incy) | ||
123 | \end{verbatim} | ||
132 | To call {\tt daxpy} from Scilab we must use a syntax as follows: | 124 | To 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 |
146 | sequence of {\tt daxpy} and {\tt ti} is the type of {\tt xi} in {\tt daxpy} | 138 | sequence 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 |
155 | which describes each output variable. {\tt [ri,ci]} is the | 148 | which describes each output variable. {\tt [ri,ci]} is the |
156 | 2 x 1 integer vector giving the number of rows and columns of the | 149 | 1 x 2 integer vector giving the number of rows and columns of the |
157 | ith output variable {\tt yi}. {\tt pi} and {\tt ti} are as for | 150 | ith output variable {\tt yi}. The position, {\tt pi}, and the type, {\tt ti}, |
158 | input variables (they can be omitted if a variable is both input and | 151 | are as for input variables (they can be omitted if a variable is both input and |
159 | output). | 152 | output). |
160 | 153 | ||
161 | We see that the arguments of {\tt call} divided into four groups. | 154 | We 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. | |||
163 | The argument {\tt 'out'} divides the remaining arguments into two | 156 | The argument {\tt 'out'} divides the remaining arguments into two |
164 | groups. The group of arguments between {\tt 'daxpy'} and {\tt 'out'} | 157 | groups. The group of arguments between {\tt 'daxpy'} and {\tt 'out'} |
165 | is the list of input arguments, their positions in the call to {\tt daxpy}, | 158 | is the list of input arguments, their positions in the call to {\tt daxpy}, |
166 | and their data type. The group of arguments to the right of {\tt 'out'} | 159 | and their data type. The group of arguments at the right of {\tt 'out'} |
167 | are the dimensions of the output variables, their positions in the call | 160 | are the dimensions of the output variables, their positions in the calling |
168 | to {\tt daxpy}, and their data type. | 161 | sequence of {\tt daxpy}, and their data type. |
169 | The possible data types are real, integer, and double precision which | 162 | The possible data types are real, integer, double and character which |
170 | are indicated, respectively, by the strings {\tt 'r'}, {\tt 'i'}, and | 163 | are indicated, respectively, by the strings {\tt 'r'}, {\tt 'i'}, {\tt 'd'} |
171 | {\tt 'd'}. | 164 | and {\tt 'c'}. |
172 | Here we calculate {\tt y=y+a*x} by a call to {\tt daxpy} (assuming | 165 | Here we calculate {\tt y=y+a*x} by a call to {\tt daxpy} (assuming |
173 | that the {\tt link} command has been done). | 166 | that the {\tt link} command has been done). |
174 | We have six input variables | 167 | We 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 |
207 | the simplified syntax | 197 | the simplified syntax |
@@ -240,19 +230,44 @@ Link done | |||
240 | 230 | ||
241 | The routines which are linked to Scilab can also access internal | 231 | The routines which are linked to Scilab can also access internal |
242 | Scilab variables: see the examples in given in the {\tt examples/links} | 232 | Scilab variables: see the examples in given in the {\tt examples/links} |
243 | directory. | 233 | directory. |
234 | |||
235 | \subsection{Building a dynamic library} | ||
236 | The simple link of an object file as illustrated above may not work on some | ||
237 | platforms. In this case, it is neccesary to build a (possibly dynamic) library | ||
238 | containing a set of programs and to link the library with Scilab. | ||
239 | Examples are given the directory {\tt SCIDIR/example/link-examples-so} | ||
240 | which are built to run in both a Linux/Unix (.so or .sl library) or | ||
241 | Windows environment (.dll library). The library is constructed by a specific | ||
242 | Scilab function {\verb!ilib_for_link!} (which make use of libtool for Unix/ | ||
243 | Linux libraries). | ||
244 | Enter \verb!-->exec ext1c.sce! at the Scilab prompt, in this directory to | ||
245 | see the simplest C example. The script file {\tt ext1c.sce} contains a call | ||
246 | to {\verb!ilib_for_link!} with appropriate parameters (files to be compiled, | ||
247 | others libraries required, etc). The library is built using the environment | ||
248 | parameters known by Scilab (compiler, linker etc). In addition a Scilab script | ||
249 | with generic name {\tt loader.sce} is created in the current directory. | ||
250 | This script contains contains the code necessary to link the library with | ||
251 | Scilab. Typically, it is a call to the {\tt link} primitive, with an | ||
252 | appropriate entry point (usually the name of the linked function). | ||
253 | Note that the script file performs two tasks: building of the library | ||
254 | and link of the library with the running Scilab. The first task is | ||
255 | generally performed once while the second should be made in every Scilab | ||
256 | session 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} |
248 | Examples of interface programs are given in the directory | 261 | Many examples of interface programs are given in the |
249 | {\tt examples/interface-tutorial} and {\tt examples/interface-tour}. | 262 | directories/subdirectories {\tt SCIDIR/examples/interface-*}. |
250 | 263 | ||
251 | The interface programs use a set of C or | 264 | The interface programs use a set of C or Fortran routines which |
252 | Fortran routines which should be used to build the interface program. | 265 | are given in {\tt SCIDIR/routines/stack-c.h} and known by Scilab |
253 | The simplest way to learn how to build an interface program is to | 266 | when this file is included in the interface program. |
254 | customize the previous skeletons files and to look at the examples | 267 | |
255 | provided in this directory. | 268 | The simplest way to learn how to build an interface program is to |
269 | look at the examples provided in the directory {\tt interface-tutorial}. | ||
270 | |||
256 | Note that a unique interface program can be used to interface an | 271 | Note that a unique interface program can be used to interface an |
257 | arbitrary (but less that $99$) number of functions. | 272 | arbitrary (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 | ||
305 | To create the Scilab function \verb!matmul!, we have to write | 320 | To create the Scilab function \verb!matmul!, we have to write |
306 | the following C gateway function called | 321 | a gateway function (an interface function). |
307 | \verb!intmatmul!. See the file \newline | 322 | A 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}. | ||
324 | These files are located in the SCIDIR/routines directory. | ||
325 | |||
326 | The following C gateway function called | ||
327 | \verb!intmatmul! is an example of interface for the matrix multiplication | ||
328 | program {\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 | |||
314 | int intmatmul(fname) | 335 | int 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 |
370 | The next step is to deal with the Scilab variables \verb!A!, \verb!B! | 391 | The next step is to deal with the Scilab variables \verb!A!, \verb!B! |
371 | and \verb!C!. In a gateway function, all the Scilab variables | 392 | and \verb!C!. In a gateway function, all the Scilab variables |
372 | are referred to as numbers. Here, the Scilab matrices | 393 | are 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 |
374 | respectively numbered \verb!1!, \verb!2! and \verb!3!. | 395 | respectively numbered \verb!1!, \verb!2! and \verb!3!. |
375 | Each input variable of the newly created Scilab function | 396 | Each 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} |
589 | The functions used to build an interface are Fortran subroutines when | 610 | The functions used to build an interface are Fortran subroutines when |
590 | the interface is written in Fortran and are coded as C macros | 611 | the interface is written in Fortran and are coded as C macros |
591 | (defined in {\tt stack-c.h} ) | 612 | when the interface is coded in C. |
592 | when the interface is coded in C. The main functions are as follows: | 613 | An interface (gateway) routine is a standard C function or Fortran |
614 | program which include the file {\tt SCIDIR/routines/stack-c.h} | ||
615 | (C coded gateway) or {\tt SCIDIR/routines/stack.h} (Fortran coded gateway). | ||
616 | |||
617 | The C functions which can be used in an interface program are available | ||
618 | as soon as {\tt SCIDIR/routines/stack-c.h} is included in the source code. | ||
619 | |||
620 | The 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 | |||
706 | given there and to adapt the code to particular needs. | 734 | given there and to adapt the code to particular needs. |
707 | 735 | ||
708 | 736 | ||
709 | \subsection{The {\tt addinter} command} | 737 | \section{Argument functions} |
710 | Once the interface program is written, it must be compiled to produce | 738 | Some built-in nonlinear solvers, such as {\tt ode} or {\tt optim}, require a |
711 | an object file. It is then linked to Scilab by the addinter command. | 739 | specific function as argument. For instance in the Scilab command |
740 | {\tt ode(x0,t0,t,fydot)}, {\tt fydot} is the specific argument function | ||
741 | for the {\tt ode} primitive. | ||
742 | This function can be a either Scilab function or an external | ||
743 | function written in C or Fortran. | ||
744 | In both cases, the argument function must obey a specific | ||
745 | syntax. In the following we will consider, as running example, using | ||
746 | the {\tt ode} primitive with a rhs function written in Fortran. The | ||
747 | same steps should be followed for all primitives which require | ||
748 | a function as argument. | ||
749 | |||
750 | If the argument function is written in C or Fortran, there | ||
751 | are 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} | ||
760 | directory (and {\tt make all} in Scilab directory). | ||
761 | The call to the {\tt ode} function is as above: | ||
762 | \begin{verbatim} | ||
763 | -->ode(x0,t0,t,'myfydot') | ||
764 | \end{verbatim} | ||
765 | \end{itemize} | ||
766 | In 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 | ||
769 | name of your function at in the appropriate list of functions. | ||
770 | \begin{verbatim} | ||
771 | ode_list= ... myfydot | ||
772 | \end{verbatim} | ||
773 | \item The {\tt Ex-ode.f} (or {\tt Ex-ode-more.f}) file: this file contains the | ||
774 | source code for argument functions. Add your function here. | ||
775 | \end{itemize} | ||
776 | |||
777 | Many exemples are provided in the {\tt default} directory. | ||
778 | More complex examples are also given. For instance it is shown | ||
779 | how to use Scilab variables as optional parameters of {\tt fydot}. | ||
712 | 780 | ||
713 | The syntax of addinter is the following: | 781 | \section{Mexfiles} |
782 | The directories under \verb!SCIDIR/examples/mexfiles! contain | ||
783 | some examples of Matlab mexfiles which can be used as interfaces | ||
784 | in the Scilab environment. The Scilab \verb!mexlib! library emulates | ||
785 | the 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 | ||
788 | of matrices (possibly sparse), structs, character strings | ||
789 | and n-dimensional arrays can be used without any modification | ||
790 | in the Scilab environment. If the source program is already compiled | ||
791 | and the mexfile given as a dynamic library, it is possible to link | ||
792 | the library with Scilab (examples are provided for Linux (.glnx extension) | ||
793 | or Windows (.dll extension)). | ||
794 | |||
795 | \section{Complements} | ||
796 | \subsection{Examining the data, function {\tt GetData}} | ||
797 | The functions {\tt GetRhsVar} and {\tt CreateVar} | ||
798 | described above for building an interface program can be used for | ||
799 | most programs involving matrices. Many other functions can be used | ||
800 | for handling Scilab more complex data such as lists. See the examples | ||
801 | in the directories examples/interfaces. | ||
802 | It is also possible to define new objects from scratch within an interface. | ||
803 | Let us first describe how to scan the Scilab objects. This can be done by the | ||
804 | function {\tt GetData}. | ||
805 | Consider the following simple interface program: | ||
806 | \begin{verbatim} | ||
807 | #include "stack-c.h" | ||
808 | void 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} | ||
817 | This interface can be built by the following Scilab script, \verb!scan.sce!: | ||
818 | \begin{verbatim} | ||
819 | ilib_name = 'libintscan'; | ||
820 | files = ['intscan.o']; | ||
821 | libs = []; | ||
822 | table = ['scan', 'intscan']; | ||
823 | ilib_build(ilib_name,table,files,libs); | ||
824 | \end{verbatim} | ||
825 | After entering \verb!-->exec scan.sce! at Scilab prompt, a file \verb!loader.sce! is made: | ||
826 | \begin{verbatim} | ||
827 | libintscan_path=get_file_path('loader.sce'); | ||
828 | functions=['scan';]; | ||
829 | addinter(libintscan_path+'/libintscan.so','libintscan',functions); | ||
830 | \end{verbatim} | ||
831 | Entering \verb!-->exec loader.sce! allows to call the new \verb!scan! function. | ||
832 | Now we can see the output of \verb!scan(A)! for, e.g., \verb!A=[4,2,3]!. | ||
833 | We see that the Scilab variable \verb!A! is represented internally by | ||
834 | a set of 4 integers (1,1,3,0) (the ``header'') followed by 3 | ||
835 | doubles (4,2,3) (the ``data''). The header is made of the following: | ||
836 | type (1 stands for ``numeric matrix''), number of rows (1 since \verb!A! | ||
837 | is a row vector), number of columns (3 since \verb!A! has three | ||
838 | columns), complex type (0 since \verb!A! is real). The data contains | ||
839 | the entries of \verb!A!. All entries are considered (and stored) as double. | ||
840 | Cleary, the function can be used to examine how Scilab variables are stored | ||
841 | internally. For instance if \verb!B=int32(A)! we see that \verb!B! is stored | ||
842 | with the header (8,1,3,4) and the int data (2,3,4). All integer matrix have | ||
843 | the type 8, and int32 receive the flag 4. | ||
844 | |||
845 | The following program shows how a matrix of strings is represented. | ||
846 | \begin{verbatim} | ||
847 | #include "stack-c.h" | ||
848 | void 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} | ||
869 | We see here that string matrices are internally represented by integers. | ||
870 | When a string matrix is passed to an interface and the | ||
871 | string matrix is processed by \verb!GetRhsVar(n,'c',&M,&N,&l)! | ||
872 | then the strings are transformed into C chars. | ||
873 | They can be obtained by the following piece of interface: | ||
874 | \begin{verbatim} | ||
875 | #include "stack-c.h" | ||
876 | void 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 | ||
717 | Here {\tt interface.o} is the object file of the interface, | 886 | Consider 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. | 889 | void 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} | ||
899 | This interface can be built by the following Scilab script, \verb!my133.sce!: | ||
900 | \begin{verbatim} | ||
901 | ilib_name = 'lib133'; | ||
902 | files = ['intmy133.o']; | ||
903 | libs = []; | ||
904 | table = ['my133', 'intmy133']; | ||
905 | ilib_build(ilib_name,table,files,libs); | ||
906 | \end{verbatim} | ||
907 | After entering \verb!-->exec my133.sce! at Scilab prompt, | ||
908 | a file \verb!loader.sce! is made, in the current directory and the new scilab | ||
909 | function \verb!my133! is available after entering \verb!-->exec loader.sce!. | ||
910 | Let us call this function. We get: | ||
911 | \begin{verbatim} | ||
912 | -->X=my133() | ||
913 | X = | ||
914 | |||
915 | Undefined display for this data type | ||
916 | -->type(X) | ||
917 | ans = | ||
918 | |||
919 | 133. | ||
920 | \end{verbatim} | ||
921 | A new variable has been created. Scilab knows its type \verb!133! which is | ||
922 | the first integer in the header, but Scilab is unable to display this variable. | ||
923 | We can attach a generic name to the type 133, by doing the following: | ||
924 | \begin{verbatim} | ||
925 | -->typename('mytype', 133) | ||
926 | \end{verbatim} | ||
927 | The 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!. | ||
930 | Now 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 | |||
939 | Cannot display this variable! | ||
940 | \end{verbatim} | ||
941 | Indeed, at this stage we have created a new type of variable, \verb!133! with | ||
942 | name {\tt mytype}. To really display the variable, we need to write a new | ||
943 | interface function. | ||
944 | Let us consider the following: | ||
945 | \begin{verbatim} | ||
946 | #include "stack-c.h" | ||
947 | void intdisp133() | ||
948 | { | ||
949 | int *header; | ||
950 | header = GetData(1); | ||
951 | header[0]=8; | ||
952 | LhsVar(1)=1; | ||
953 | } | ||
954 | \end{verbatim} | ||
955 | This function does nothing, except changing \verb!header[0]! from 133 to | ||
956 | 8. | ||
957 | We can build a library with the two functions \verb!my133! and \verb!disp133! | ||
958 | with the scilab script: | ||
959 | \begin{verbatim} | ||
960 | ilib_name = 'lib133'; | ||
961 | files = ['intmy133.o', 'intdisp133.o']; | ||
962 | libs = []; | ||
963 | table = ['my133', 'intmy133'; | ||
964 | 'disp133' ,'intdisp133']; | ||
965 | ilib_build(ilib_name,table,files,libs); | ||
966 | \end{verbatim} | ||
721 | 967 | ||
968 | We can redefined the display function for variables tagged \verb!"mytype"! | ||
969 | by \verb!typename!. | ||
970 | \begin{verbatim} | ||
971 | -->function %mytype_p(X) | ||
972 | -->disp(disp133(X)) | ||
973 | -->endfunction | ||
974 | |||
975 | -->X | ||
976 | X = | ||
977 | |||
978 | 35 | ||
979 | \end{verbatim} | ||
980 | When \verb!X! is typed at the scilab prompt, the function \verb!%mytype! | ||
981 | is searched to display \verb!X!, since \verb!X! is a variable of type 133 | ||
982 | and such variables have the generic name "mytype", set by the command | ||
983 | \verb!typename('mytype',133)!. The function \verb!disp133! transforms the | ||
984 | variable 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} | ||
988 | By default, the arguments given to the interface are passed ``by value''. | ||
989 | This means that, in the interface program, one is working with a copy | ||
990 | of the Scilab data. Consider for instance the following gateway function: | ||
991 | \begin{verbatim} | ||
992 | #include "stack-c.h" | ||
993 | void 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} | ||
1000 | for the Scilab function {\tt X=tstfct(A)}. We assume that the variable \verb!A! | ||
1001 | passed to \verb!tstfct! is a standard real matrix. | ||
1002 | Note that we could use the following gateway which performs the same job. | ||
1003 | \begin{verbatim} | ||
1004 | #include "stack-c.h" | ||
1005 | void 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} | ||
1013 | This function is installed into Scilab by executing the script | ||
1014 | \begin{verbatim} | ||
1015 | ilib_name = 'libinttstfct'; | ||
1016 | files = ['inttstfct.o']; | ||
1017 | libs = []; | ||
1018 | table = ['tstfct', 'inttstfct']; | ||
1019 | ilib_build(ilib_name,table,files,libs); | ||
1020 | \end{verbatim} | ||
1021 | and executing the newly created script \verb!loader.sce!. | ||
1022 | |||
1023 | Assume also that \verb!A! is the 2 x 2 matrix \verb!A=zeros(2,2)!, | ||
1024 | and consider the Scilab command \verb!-->B=tstfct(A)!. In the interface | ||
1025 | program, before its assignment, \verb!stk(l1)[0]! is equal to 0, i.e. the first | ||
1026 | entry of \verb!A!, {\tt A(1,1)}. | ||
1027 | The output {\tt B} will be, as expected, the Scilab matrix \verb![1 0;0 0]!. | ||
1028 | But the Scilab variable {\tt A} will not be modified. This behavior is similar | ||
1029 | with the usual Scilab functions: the input parameters of the function are | ||
1030 | not modified when the function is called. | ||
1031 | It is however possible to pass the parameters by reference. This can be useful | ||
1032 | if the interfaced program do not alter the input data (the data can be used | ||
1033 | in read-only mode). | ||
1034 | Let us enter the command \verb!-->funptr tstfct!. We get: | ||
1035 | \begin{verbatim} | ||
1036 | -->funptr tstfct | ||
1037 | ans = | ||
1038 | |||
1039 | 50101. | ||
1040 | \end{verbatim} | ||
1041 | which means: the function \verb!tstfct! has number \verb!01! in interface | ||
1042 | number \verb!501!. | ||
1043 | It is possible to convert the gateway function into a gateway in which the | ||
1044 | variables are passed by reference. This is done as follows | ||
1045 | by 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} | ||
1054 | Note that if several Scilab functions are built together in the same | ||
1055 | inerface they will all receive input parameters as reference. | ||
1056 | The 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} | ||
1075 | Finally, we note that the function {\tt GetRawData} gives the | ||
1076 | internal representation of the reference variable and {\tt GetData} | ||
1077 | gives the internal representation of the value variable pointed to | ||
1078 | by the reference. | ||
722 | \section{Intersci} | 1079 | \section{Intersci} |
723 | The directory \verb!SCIDIR/examples/intersci-examples-so! contains | 1080 | The directory \verb!SCIDIR/examples/intersci-examples-so! contains |
724 | several examples for using \verb!intersci! which is a tool for | 1081 | several 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 | |||
778 | int intsext1c(fname) | 1134 | int 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. | |||
831 | The keywords which describe the Scilab function and the function | 1187 | The keywords which describe the Scilab function and the function |
832 | to be called can be found in the examples given. | 1188 | to be called can be found in the examples given. |
833 | 1189 | ||
834 | \section{Argument functions} | ||
835 | Some built-in nonlinear solvers, such as {\tt ode} or {\tt optim}, require a | ||
836 | specific function as argument. For instance in the Scilab command | ||
837 | {\tt ode(x0,t0,t,fydot)}, {\tt fydot} is the specific argument function | ||
838 | for the {\tt ode} primitive. | ||
839 | This function can be a either Scilab function or an external | ||
840 | function written in C or Fortran. | ||
841 | In both cases, the argument function must obey a specific | ||
842 | syntax. In the following we will consider, as running example, using | ||
843 | the {\tt ode} primitive with a rhs function written in Fortran. The | ||
844 | same steps should be followed for all primitives which require | ||
845 | a function as argument. | ||
846 | |||
847 | If the argument function is written in C or Fortran, there | ||
848 | are 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} | ||
857 | directory (and {\tt make all} in Scilab directory). | ||
858 | The call to the {\tt ode} function is as above: | ||
859 | \begin{verbatim} | ||
860 | -->ode(x0,t0,t,'myfydot') | ||
861 | \end{verbatim} | ||
862 | \end{itemize} | ||
863 | In 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 | ||
866 | name of your function at in the appropriate list of functions. | ||
867 | \begin{verbatim} | ||
868 | ode_list= ... myfydot | ||
869 | \end{verbatim} | ||
870 | \item The {\tt Ex-ode.f} (or {\tt Ex-ode-more.f}) file: this file contains the | ||
871 | source code for argument functions. Add your function here. | ||
872 | \end{itemize} | ||
873 | |||
874 | Many exemples are provided in the {\tt default} directory. | ||
875 | More complex examples are also given. For instance it is shown | ||
876 | how to use Scilab variables as optional parameters of {\tt fydot}. | ||
877 | \section{Mexfiles} | ||
878 | The directories under \verb!SCIDIR/examples/mexfiles! contain | ||
879 | some examples of Matlab mexfiles which can be used as interfaces | ||
880 | in the Scilab environment. The Scilab \verb!mexlib! library emulates | ||
881 | the 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 | ||
884 | of matrices (possibly sparse), character strings and n-dimensional arrays | ||
885 | can be used without any modification in the Scilab environment. | ||
886 | |||
887 | \section{Maple to Scilab Interface} | ||
888 | To combine symbolic computation of the computer algebra system Maple with the | ||
889 | numerical facilities | ||
890 | of Scilab, Maple objects can be transformed into Scilab functions. To assure | ||
891 | efficient numerical evaluation this is done through numerical evaluation in | ||
892 | Fortran. The whole process is done by a Maple procedure called | ||
893 | \verb/maple2scilab/. | ||
894 | \section{Maple2scilab} | ||
895 | \index{maple2scilab@{\tt maple2scilab}} | ||
896 | The procedure \verb!maple2scilab! converts a Maple object, | ||
897 | either a scalar function or a matrix into a Fortran subroutine | ||
898 | and writes the associated Scilab function. The code of \verb!maple2scilab! | ||
899 | is in the directory \verb!SCIDIR/maple!. | ||
900 | |||
901 | The calling sequence of \verb!maple2scilab! is as follows:\\ | ||
902 | \verb!maple2scilab(function-name,object,args)! | ||
903 | \begin{itemize} | ||
904 | \item | ||
905 | The first argument, \verb!function-name! is a name indicating the | ||
906 | function-name in Scilab. | ||
907 | \item | ||
908 | The second argument \verb!object! is the Maple name of the expression | ||
909 | to be transferred to Scilab. | ||
910 | \item | ||
911 | The third argument is a list of arguments containing the formal parameters of | ||
912 | the Maple-object \verb!object!. | ||
913 | \end{itemize} | ||
914 | When \verb!maple2scilab! is invoked in Maple, two files are generated, | ||
915 | one which contains the Fortran code and another which contains the | ||
916 | associated Scilab function. Aside their existence, the user has not to | ||
917 | know about their contents. | ||
918 | |||
919 | The Fortran routine which is generated has the following calling sequence:\\ | ||
920 | {\tt <Scilab-name>(x1,x2,\ldots,xn,matrix)} \\ | ||
921 | and this subroutine computes matrix(i,j) as a function of | ||
922 | the arguments {\tt x1,x2,\ldots,xn}. | ||
923 | Each argument can be a Maple scalar or array which should be | ||
924 | in the argument list. | ||
925 | The Fortran subroutine is put into a file named {\tt <Scilab-name>.f}, the | ||
926 | Scilab-function into a file named {\tt <Scilab-name>.sci}. | ||
927 | For numerical evaluation in Scilab the user has to compile the Fortran | ||
928 | subroutine, to link it with Scilab (e.g. Menu-bar option '\verb!link!') | ||
929 | and to load the associated function (Menu-bar option '\verb!getf!'). | ||
930 | Information about \verb!link! operation is given in Scilab's manual: | ||
931 | Fortran routines can be incorporated into Scilab by dynamic | ||
932 | link 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). | ||
935 | Maple2scilab uses the ``Macrofort'' library which is in the share | ||
936 | library 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} | ||
947 | Here the Maple variable \verb!f! is a scalar expression but it could be also | ||
948 | a 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). | ||
951 | The procedure \verb/maple2scilab/ creates two files: \verb/f_m.f/ | ||
952 | and \verb/f_m.sci/ in the directory where Maple is started. | ||
953 | To specify another directory just define in Maple the path : | ||
954 | \verb/rpath:=`//\verb/work//` ; then all files are written in | ||
955 | the sub-directory \verb/work/. | ||
956 | The file \verb!f_m.f! contains the source code of a stand alone Fortran | ||
957 | routine which is dynamically linked to Scilab by the function \verb!f_m! in | ||
958 | defined 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 | |||
966 | linking _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} | ||
977 | This 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 | |||
1001 | linking _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} | ||
1017 | Below is the code (Fortran subroutines and Scilab functions) which is | ||
1018 | automatically generated by {\tt maple2scilab} in the two preceding examples. | ||
1019 | \paragraph{Fortran routines} | ||
1020 | \begin{verbatim} | ||
1021 | c | ||
1022 | c SUBROUTINE f_m | ||
1023 | c | ||
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} | ||
1032 | c | ||
1033 | c SUBROUTINE mat | ||
1034 | c | ||
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} | ||
1048 | function [var]=f_m(x,a,b) | ||
1049 | var=call('f_m',x,1,'d',a,2,'d',b,3,'d','out',[1,1],4,'d') | ||
1050 | \end{verbatim} | ||
1051 | \begin{verbatim} | ||
1052 | function [var]=fmat(x,par) | ||
1053 | var=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 | ||