4af47090bf77ca45b6c660a790aa7c30d53bfb2c
[scilab.git] / scilab / modules / xcos / help / en_US / programming_scicos_blocks / c_computational_functions / C_struct.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3  * Scicos
4  * 
5  * Copyright (C) INRIA - METALAU Project <scicos@inria.fr> (HTML version)
6  * Copyright (C) DIGITEO - Scilab Consortium (XML Docbook version)
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  * 
22  * See the file ./license.txt
23  -->
24 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="C_struct">
25     <refnamediv>
26         <refname>C_struct</refname>
27         <refpurpose>C Block structure of a computational function</refpurpose>
28     </refnamediv>
29     <refsynopsisdiv>
30         <title>Description</title>
31         
32     </refsynopsisdiv>
33     <refsection id="Contents_C_struct">
34         <title>Contents</title>
35         <itemizedlist>
36             <listitem>
37                 <para>
38                     <link linkend="C_struct">C_struct - C Block structure of a computational function</link>
39                 </para>
40             </listitem>
41             <listitem>
42                 <itemizedlist>
43                     <listitem>
44                         <para>
45                             <xref linkend="Module_C_struct">Module</xref>
46                         </para>
47                     </listitem>
48                     <listitem>
49                         <para>
50                             <xref linkend="Description_C_struct">Description</xref>
51                         </para>
52                     </listitem>
53                     <listitem>
54                         <para>
55                             <xref linkend="Inputsoutputs_C_struct">Inputs/outputs</xref>
56                         </para>
57                     </listitem>
58                     <listitem>
59                         <para>
60                             <xref linkend="Events_C_struct">Events</xref>
61                         </para>
62                     </listitem>
63                     <listitem>
64                         <para>
65                             <xref linkend="Parameters_C_struct">Parameters</xref>
66                         </para>
67                     </listitem>
68                     <listitem>
69                         <para>
70                             <xref linkend="Statesandwork_C_struct">States and work</xref>
71                         </para>
72                     </listitem>
73                     <listitem>
74                         <para>
75                             <xref linkend="Zerocrossingsurfacesandmodes_C_struct">Zero crossing surfaces and modes</xref>
76                         </para>
77                     </listitem>
78                     <listitem>
79                         <para>
80                             <xref linkend="Miscallaneous_C_struct">Miscallaneous</xref>
81                         </para>
82                     </listitem>
83                 </itemizedlist>
84             </listitem>
85         </itemizedlist>
86     </refsection>
87     <refsection id="Module_C_struct">
88         <title>Module</title>
89         <itemizedlist>
90             <listitem>
91                 <para>
92                     <link linkend="xcos">xcos</link>
93                 </para>
94             </listitem>
95         </itemizedlist>
96     </refsection>
97     <refsection id="Description_C_struct">
98         <title>Description</title>
99         <para>
100             The C structure of a Scicos block defines all the fields to handle data provided by the simulator such inputs/outputs, parameters, states, ...
101         </para>
102         <para>
103             That structure of type <literal>scicos_block</literal> is defined in the file <literal>scicos_block4.h</literal> included into the standard Scilab distribution, and users must include that header in each computational functions.
104         </para>
105         <para>
106             This access is a direct approach and most of users should prefer the <link linkend="C_macros">C macros</link> approach for facilities purpose. 
107         </para>
108     </refsection>
109     <refsection id="Inputsoutputs_C_struct">
110         <title>Inputs/outputs</title>
111         <itemizedlist>
112             <listitem>
113                 <para>
114                     <emphasis role="bold">block-&gt;nin :</emphasis> Integer that gives the number of regular input ports of the block.
115                 </para>
116                 <para>
117                     One can't override the index <literal>(3*block-&gt;nin)-1</literal> when reading sizes of input ports in the array <literal>insz</literal> and the index <literal>block-&gt;nin-1</literal> when reading data in the array <literal>inptr</literal> with a C computational function.
118                     The number of regular input ports can also be got by the use of the C macros <literal>GetNin(block)</literal>. 
119                 </para>
120             </listitem>
121             <listitem>
122                 <para>
123                     <emphasis role="bold">block-&gt;insz :</emphasis> An array of integers of size <literal>(3*block-&gt;nin)-1</literal> that respectively gives the first dimensions, the second dimensions and the type of data driven by regular input ports.
124                 </para>
125                 <para>
126                      Note that this array of size differs from the array <literal>ozsz</literal> and <literal>oparsz</literal> to provide full compatibility with blocks that only use a single dimension.
127                 </para>
128                 <para>Suppose that you have a block with three inputs : the first is an int32 matrix of size [3,2], the second a single complex number (matrix of size [1,1]) and the last a real matrix of size [4,1].</para>
129                 <para>
130                     In the<link linkend="scicos_model">scicos_model</link> of such a block, the inputs will be defined :
131                 </para>
132                 <programlisting role="scilab">
133                     model = scicos_model();
134                     model.in = [3;1;4];
135                     model.in2 = [2;1;1];
136                     model.intyp = [2;1;3];
137                 </programlisting>
138                 <para>
139                     and the corresponding <literal>block-&gt;insz</literal> field at C computational function level will be coded as :
140                 </para>
141                 <mediaobject>
142                     <imageobject>
143                         <imagedata fileref="../../../images/programming_scicos_blocks/c_computational_functions/en_US/C_struct_img1_en_US.gif"/>
144                     </imageobject>
145                     <textobject>
146                         <programlisting role="pic"><![CDATA[
147 .PS
148 Dim1start: box "3"; Dim1center: box "1"; Dim1end: box "4";
149 Dim2start: box "2"; Dim2center: box "1"; Dim2end: box "1";
150 Typestart: box "84"; Typecenter: box "11"; Typeend: box "10";
151
152 {"insz[0]" at Dim1start .n + (0, 0.2);}
153 {"insz[nin]" at Dim2start .n + (0, 0.2);}
154 {"insz[2*nin]" at Typestart .n + (0, 0.2);}
155
156 boxwid=Dim1start.wid * 3;
157 boxht=Dim1start.ht * 0.5;
158 {box "First dimension" at Dim1center .s + (0, -0.5);}
159 {box "Second dimension" at Dim2center .s + (0, -0.5);}
160 {box "Type" at Typecenter .s + (0, -0.5);}
161 .PE
162                         ]]></programlisting>
163                     </textobject>
164                 </mediaobject>
165                 <para>
166                     Do the difference here in the type numbers defined at the <emphasis role="bold">Scilab level</emphasis> (2,1,3) and the type numbers defined at the <emphasis role="bold">C level</emphasis> (84,11,10). The following table gives the correspondance for all Scicos type:
167                 </para>
168                 <informaltable border="1" cellpadding="3">
169                     <tr>
170                         <td align="left">
171                             <emphasis role="bold">Scilab Type</emphasis>
172                         </td>
173                         <td align="left">
174                             <emphasis role="bold">Scilab Number</emphasis>
175                         </td>
176                         <td align="left">
177                             <emphasis role="bold">C Type</emphasis>
178                         </td>
179                         <td align="left">
180                             <emphasis role="bold">C Number</emphasis>
181                         </td>
182                     </tr>
183                     <tr>
184                         <td align="left">real</td>
185                         <td align="left">1</td>
186                         <td align="left">double</td>
187                         <td align="left">10</td>
188                     </tr>
189                     <tr>
190                         <td align="left">complex</td>
191                         <td align="left">2</td>
192                         <td align="left">double</td>
193                         <td align="left">11</td>
194                     </tr>
195                     <tr>
196                         <td align="left">int32</td>
197                         <td align="left">3</td>
198                         <td align="left">long</td>
199                         <td align="left">84</td>
200                     </tr>
201                     <tr>
202                         <td align="left">int16</td>
203                         <td align="left">4</td>
204                         <td align="left">short</td>
205                         <td align="left">82</td>
206                     </tr>
207                     <tr>
208                         <td align="left">int8</td>
209                         <td align="left">5</td>
210                         <td align="left">char</td>
211                         <td align="left">81</td>
212                     </tr>
213                     <tr>
214                         <td align="left">uint32</td>
215                         <td align="left">6</td>
216                         <td align="left">unsigned long</td>
217                         <td align="left">814</td>
218                     </tr>
219                     <tr>
220                         <td align="left">uint16</td>
221                         <td align="left">7</td>
222                         <td align="left">unsigned short</td>
223                         <td align="left">812</td>
224                     </tr>
225                     <tr>
226                         <td align="left">uint8</td>
227                         <td align="left">8</td>
228                         <td align="left">unsigned char</td>
229                         <td align="left">811</td>
230                     </tr>
231                 </informaltable>
232             </listitem>
233             <listitem>
234                 <para>
235                     <emphasis role="bold">block-&gt;inptr :</emphasis> An array of pointers of size nin,1 that allow to directly access to the data contained in the regular input matrices.
236                 </para>
237                 <para>Suppose the previous example (block with three inputs : an int32 matrix of size [3,2], a complex scalar and a real matrix of size [4,1]).</para>
238                 <para>
239                     <literal>block-&gt;inptr</literal> contains three pointers, and should be viewed as arrays contained the data for the int32, the real and the complex matrices :
240                 </para>
241                 <mediaobject>
242                     <imageobject>
243                         <imagedata fileref="../../../images/programming_scicos_blocks/c_computational_functions/en_US/C_struct_img2_en_US.gif"/>
244                     </imageobject>
245                     <textobject>
246                         <programlisting role="pic"><![CDATA[
247 .PS
248 down;
249 Inptr0ptr: box "long*";Inptr1ptr: box "double*";Inptr2ptr: box "double*";
250
251 Inptr0: box at Inptr0ptr.e + (2.0, 3.0);box;box;box;box;box;
252 move;
253 Inptr1: box; box;
254 move;
255 Inptr2: box;box;box;box;
256
257 right;
258 line at Inptr0ptr.e; arc; line; line; line; arc cw; arrow;
259 line at Inptr1ptr.e; line; arrow;
260 line at Inptr2ptr.e; arc cw; line; line; arc; arrow;
261
262 {"inptr" at Inptr0ptr.n + (0, 0.2);}
263 {"inptr[0]" at Inptr0 .n + (0, 0.2);}
264 {"inptr[1]" at Inptr1 .n + (0, 0.2);}
265 {"inptr[2]" at Inptr2 .n + (0, 0.2);}
266
267 "inptr[0][0]" ljust at Inptr0.e + (0.1, 0);
268 "inptr[0][1]" ljust at Inptr0.e + (0.1, -0.5);
269 "inptr[0][2]" ljust at Inptr0.e + (0.1, -1.0);
270 "inptr[0][3]" ljust at Inptr0.e + (0.1, -1.5);
271 "inptr[0][4]" ljust at Inptr0.e + (0.1, -2.0);
272 "inptr[0][5]" ljust at Inptr0.e + (0.1, -2.5);
273
274 "inptr[1][0] - Real part" ljust at Inptr1.e + (0.1, 0);
275 "inptr[1][1] - Imaginary part" ljust at Inptr1.e + (0.1, -0.5);
276
277 "inptr[2][0]" ljust at Inptr2.e + (0.1, 0);
278 "inptr[2][1]" ljust at Inptr2.e + (0.1, -0.5);
279 "inptr[2][2]" ljust at Inptr2.e + (0.1, -1.0);
280 "inptr[2][3]" ljust at Inptr2.e + (0.1, -1.5);
281 .PE
282                         ]]></programlisting>
283                     </textobject>
284                 </mediaobject>
285                 <para>
286                     For i.e., to directly access to the data, the user can use theses instructions :   
287                 </para>
288                 <programlisting role="c"><![CDATA[
289 #include "scicos_block4.h"
290
291 ...
292
293 SCSINT32_COP *ptr_i;
294 SCSCOMPLEX_COP *ptr_dc;
295 SCSREAL_COP *ptr_d;
296 int n1,m1;
297 SCSINT32_COP cumsum_i=0;
298 int i;
299
300 void mycomputfunc(scicos_block *block,int flag)
301 {
302     ...
303     
304     /*get the ptrs of the first int32 regular input port*/
305     ptr_i = (SCSINT32_COP *) block->inptr[0];
306     /*get the ptrs of the second complex regular input port*/
307     ptr_dc = (SCSCOMPLEX_COP *) block->inptr[1];
308     /*get the ptrs of the third real regular input port*/
309     ptr_d = (SCSREAL_COP *) block->inptr[2];
310     
311     ...
312     
313     /*get the dimension of the first int32 regular input port*/
314     n1=block->insz[0];
315     m1=block->insz[3];
316     
317     /*compute the cumsum of the input int32 matrix*/
318     for(i=0;i<n1*m1;i++) {
319         cumsum_i += ptr_i[i];
320     }
321     ...
322 }]]></programlisting>
323                 <para>
324                     One can also use the set of C macros : <literal>GetInPortPtrs(blk,x)</literal>, <literal>GetRealInPortPtrs(block,x)</literal>, <literal>GetImagInPortPtrs(block,x)</literal>, <literal>Getint8InPortPtrs(block,x)</literal>, <literal>Getint16InPortPtrs(block,x)</literal>, <literal>Getint32InPortPtrs(block,x)</literal>, <literal>Getuint8InPortPtrs(block,x)</literal>, <literal>Getuint16InPortPtrs(block,x)</literal>, <literal>Getuint32InPortPtrs(block,x)</literal> to have the appropriate pointer of the data to handle and <literal>GetNin(block)</literal>, <literal>GetInPortRows(block,x)</literal>, <literal>GetInPortCols(block,x)</literal>, <literal>GetInPortSize(block,x,y)</literal>, <literal>GetInType(block,x)</literal>, <literal>GetSizeOfIn(block,x)</literal> to handle number, dimensions and type of regular input ports.
325                     (<emphasis role="bold">x is numbered from 1 to nin and y numbered  from 1 to 2</emphasis>).
326                 </para>
327                 <para> 
328                     For the previous example that gives :
329                 </para>
330                 <programlisting role="c"><![CDATA[
331 #include "scicos_block4.h"
332
333 ...
334
335 SCSINT32_COP *ptr_i;
336 SCSCOMPLEX_COP *ptr_dc;
337 SCSREAL_COP *ptr_d;
338 int n1,m1;
339 SCSINT32_COP cumsum_i=0;
340 int i;
341
342 void mycomputfunc(scicos_block *block,int flag)
343 {
344     ...
345     
346     /*get the ptrs of the first int32 regular input port*/
347     ptr_i = Getint32InPortPtrs(block,1);
348     /*get the ptrs of the second complex regular input port*/
349     ptr_dc = GetRealInPortPtrs(block,2);
350     /*get the ptrs of the third real regular input port*/
351     ptr_d = GetRealInPortPtrs(block,3);
352     
353     ...
354     
355     /*get the dimension of the first int32 regular input port*/
356     n1=GetInPortRows(block,1);
357     m1=GetInPortCols(block,1);
358     
359     ...
360 }]]></programlisting>
361                 <para>
362                     Finally note that the regular input port registers are only accessible for reading.
363                 </para>
364             </listitem>
365             <listitem>
366                 <para>
367                     <emphasis role="bold">block-&gt;nout :</emphasis> Integer that gives the number of regular output ports of the block.
368                 </para>
369                 <para>
370                     One can't override the index <literal>(3*block-&gt;nout)-1</literal> when reading sizes of output ports in the array <literal>outsz</literal> and the index <literal>block-&gt;nout-1</literal> when reading data in the array <literal>outptr</literal>with a C computational function.
371                 </para>
372                 <para>
373                      The number of regular output ports can also be got by the use of the C macros <literal>GetNout(block)</literal> . 
374                 </para>
375             </listitem>
376             <listitem>
377                 <para>
378                     <emphasis role="bold">block-&gt;outsz :</emphasis> An array of integers of size <literal>(3*block-&gt;nout)-1</literal> that respectively gives the first dimensions, the second dimensions and the type of data driven by regular output ports.
379                 </para>
380                 <para>
381                     Note that this array of size differs from the array <literal>ozsz</literal> and <literal>oparsz</literal> to provide full compatibility with blocks that only use a single dimension.
382                 </para>
383                 <para>Suppose that you have a block with two outputs : the first is an int32 matrix of size [3,2], the second a single complex number (matrix of size 1,1) and the last a real matrix of size [4,1].</para>
384                 <para>
385                     In the<link linkend="scicos_model">scicos_model</link> of such a block, the outputs will be defined :
386                 </para>
387                 <programlisting role="code"><![CDATA[
388 model = scicos_model();
389 model.out = [3;1;4];
390 model.out2 = [2;1;1]; 
391 model.outtyp = [2;1;3];
392                      ]]></programlisting>
393                 <para>
394                     and the corresponding <literal>block-&gt;outsz</literal> field at C computational function level will be coded as :
395                 </para>
396                 <mediaobject>
397                     <imageobject>
398                         <imagedata fileref="../../../images/programming_scicos_blocks/c_computational_functions/en_US/C_struct_img3_en_US.gif"/>
399                     </imageobject>
400                     <textobject>
401                         <programlisting role="pic"><![CDATA[
402 .PS
403 Dim1start: box "3"; Dim1center: box "1"; Dim1end: box "4";
404 Dim2start: box "2"; Dim2center: box "1"; Dim2end: box "1";
405 Typestart: box "84"; Typecenter: box "11"; Typeend: box "10";
406
407 {"outsz[0]" at Dim1start .n + (0, 0.2);}
408 {"outsz[nin]" at Dim2start .n + (0, 0.2);}
409 {"outsz[2*nin]" at Typestart .n + (0, 0.2);}
410
411 boxwid=Dim1start.wid * 3;
412 boxht=Dim1start.ht * 0.5;
413 {box "First dimension" at Dim1center .s + (0, -0.5);}
414 {box "Second dimension" at Dim2center .s + (0, -0.5);}
415 {box "Type" at Typecenter .s + (0, -0.5);}
416 .PE
417                         ]]></programlisting>
418                     </textobject>
419                 </mediaobject>
420                 <para>
421                     Do the difference here in the type numbers defined at the <emphasis role="bold">Scilab level</emphasis> (2,1,3)
422                     and the type numbers defined at the <emphasis role="bold">C level</emphasis> (84,11,10) and please report to the previous table to have the correspondence for all Scicos type.
423                 </para>
424             </listitem>
425             <listitem>
426                 <para>
427                     <emphasis role="bold">block-&gt;outptr :</emphasis> An array of pointers of size [nout,1] that allow to directly acces to the data contained in the regular output matrices.
428                 </para>
429                 <para> Suppose the previous example (block with three outputs : an int32 matrix of size [3,2], a complex scalar and a real matrix of size [4,1]).</para>
430                 <para>
431                     <literal>block-&gt;outptr</literal> contains three pointers, and should be viewed as arrays contained the data for the int32, the real and the complex matrices :
432                 </para>
433                 <mediaobject>
434                     <imageobject>
435                         <imagedata fileref="../../../images/programming_scicos_blocks/c_computational_functions/en_US/C_struct_img4_en_US.gif"/>
436                     </imageobject>
437                     <textobject>
438                         <programlisting role="pic"><![CDATA[
439 .PS
440 down;
441 Outptr0ptr: box "long*";Outptr1ptr: box "double*";Outptr2ptr: box "double*";
442
443 Outptr0: box at Outptr0ptr.e + (2.0, 3.0);box;box;box;box;box;
444 move;
445 Outptr1: box; box;
446 move;
447 Outptr2: box;box;box;box;
448
449 right;
450 line at Outptr0ptr.e; arc; line; line; line; arc cw; arrow;
451 line at Outptr1ptr.e; line; arrow;
452 line at Outptr2ptr.e; arc cw; line; line; arc; arrow;
453
454 {"outptr" at Outptr0ptr.n + (0, 0.2);}
455 {"outptr[0]" at Outptr0 .n + (0, 0.2);}
456 {"outptr[1]" at Outptr1 .n + (0, 0.2);}
457 {"outptr[2]" at Outptr2 .n + (0, 0.2);}
458
459 "outptr[0][0]" ljust at Outptr0.e + (0.1, 0);
460 "outptr[0][1]" ljust at Outptr0.e + (0.1, -0.5);
461 "outptr[0][2]" ljust at Outptr0.e + (0.1, -1.0);
462 "outptr[0][3]" ljust at Outptr0.e + (0.1, -1.5);
463 "outptr[0][4]" ljust at Outptr0.e + (0.1, -2.0);
464 "outptr[0][5]" ljust at Outptr0.e + (0.1, -2.5);
465
466 "outptr[1][0] - Real part" ljust at Outptr1.e + (0.1, 0);
467 "outptr[1][1] - Imaginary part" ljust at Outptr1.e + (0.1, -0.5);
468
469 "outptr[2][0]" ljust at Outptr2.e + (0.1, 0);
470 "outptr[2][1]" ljust at Outptr2.e + (0.1, -0.5);
471 "outptr[2][2]" ljust at Outptr2.e + (0.1, -1.0);
472 "outptr[2][3]" ljust at Outptr2.e + (0.1, -1.5);
473 .PE
474                         ]]></programlisting>
475                     </textobject>
476                 </mediaobject>
477                 <para>
478                     For i.e., to directly access to the data, the user can use theses instructions :
479                     
480                 </para>
481                 <programlisting role="c"><![CDATA[
482 #include "scicos_block4.h"
483
484 SCSINT32_COP *ptr_i;
485 SCSCOMPLEX_COP *ptr_dc;
486 SCSREAL_COP *ptr_d;
487 int n1,m1;
488 SCSINT32_COP cumsum_i=0;
489 int i;
490
491 void mycomputfunc(scicos_block *block,int flag)
492 {
493     /*get the ptrs of the first int32 regular output port*/
494     ptr_i = (SCSINT32_COP *) block->outptr[0];
495     /*get the ptrs of the second complex regular output port*/
496     ptr_dc = (SCSCOMPLEX_COP *) block->outptr[1];
497     /*get the ptrs of the third real regular output port*/
498     ptr_d = (SCSREAL_COP *) block->outptr[2];
499
500     /*get the dimension of the first int32 regular output port*/
501     n1=block->outsz[0];
502     m1=block->outsz[3];
503
504     /*compute the cumsum of the output int32 matrix*/
505     for(i=0;i<n1*m1;i++) {
506         cumsum_i += ptr_i[i];
507     }
508 }
509                     ]]></programlisting>
510                 <para>One can also use the set of C macros : 
511                     <literal>GetOutPortPtrs(block,x)</literal>, <literal>GetRealOutPortPtrs(block,x)</literal>, <literal>GetImagOutPortPtrs(block,x)</literal>, <literal>Getint8OutPortPtrs(block,x)</literal>, <literal>Getint16OutPortPtrs(block,x)</literal>, <literal>Getint32OutPortPtrs(block,x)</literal>, <literal>Getuint8OutPortPtrs(block,x)</literal>, <literal>Getuint16OutPortPtrs(block,x)</literal>, <literal>Getuint32OutPortPtrs(block,x)</literal> to have the appropriate pointer of the data to handle and <literal>GetNout(block)</literal>, <literal>GetOutPortRows(block,x)</literal>, <literal>GetOutPortCols(block,x)</literal>, <literal>GetOutPortSize(block,x,y)</literal>, <literal>GetOutType(block,x)</literal>, <literal>GetSizeOfOut(block,x)</literal>to handle number, dimensions and type of regular output ports. (<emphasis role="bold">x is numbered from 1 to nout and y is numbered  from 1 to 2</emphasis>).
512                 </para>
513                 <para>
514                     For the previous example that gives :
515                 </para>
516                 <programlisting role="c"><![CDATA[
517 #include "scicos_block4.h"
518
519 SCSINT32_COP *ptr_i;
520 SCSCOMPLEX_COP *ptr_dc;
521 SCSREAL_COP *ptr_d;
522 int n1,m1;
523 SCSINT32_COP cumsum_i=0;
524 int i;
525
526 void mycomputfunc(scicos_block *block,int flag)
527 {
528     ...
529     
530     /*get the ptrs of the first int32 regular output port*/
531     ptr_i = GetOutPortPtrs(block,1);
532     /*get the ptrs of the second complex regular output port*/
533     ptr_dc = GetRealOutPortPtrs(block,2);
534     /*get the ptrs of the third real regular output port*/
535     ptr_d = GetRealOutPortPtrs(block,3);
536     ...
537     
538     /*get the dimension of the first int32 regular output port*/
539     n1=GetOutPortRows(block,1);
540     m1=GetOutPortCols(block,1);
541     ...
542     
543 }
544 ]]></programlisting>
545                 <para>
546                     Finally note that the regular output port registers must be only written for <literal>flag=1</literal>.
547                 </para>
548             </listitem>
549         </itemizedlist>
550     </refsection>
551     <refsection id="Events_C_struct">
552         <title>Events</title>
553         <itemizedlist>
554             <listitem>
555                 <para>
556                     <emphasis role="bold">block-&gt;nevprt :</emphasis> Integer that gives the event input port number by which the block has been activated. This number is a binary coding. For i.e, if block has two event inputs ports, <literal> block-&gt;nevptr</literal>can take the value <literal>1</literal> if the block has been called by its first event input port, the value <literal>2</literal> if it has been called by the second event input port and <literal>3</literal> if it is called by the same event on both input port 1 and 2.
557                 </para>
558                 <para>
559                      Note that can be <literal>-1</literal> if the block is internally called.
560                 </para>
561                 <para>
562                      One can also retrieve this number by using the C macros <literal>GetNevIn(block)</literal>
563                 </para>
564             </listitem>
565             <listitem>
566                 <para>
567                     <emphasis role="bold">block-&gt;nevout :</emphasis> Integer that gives the number of event output ports of the block (also called the length of the output event register).
568                 </para>
569                 <para>
570                      One can't override the index <literal>block-&gt;nevout-1</literal> when setting value of events in the output event register <literal>evout</literal>.
571                 </para>
572                 <para>
573                      The number of event output ports can also be got by the use of the C macro <literal>GetNevOut(block)</literal>. 
574                 </para>
575             </listitem>
576             <listitem>
577                 <para>
578                     <emphasis role="bold">block-&gt;evout :</emphasis> Array of double of size [nevout,1] corresponding to the output event register. That register is used to program date of events during the simulation.
579                 </para>
580                 <para> When setting values in that array, you must understand that you give a delay relative to the current time of simulator :</para>
581                 <latex>
582                     $$
583                     t_{event} = t_{current} + T_{delay}
584                     $$
585                 </latex>
586                 <para>
587                     where <latex>$t_{event}$</latex> is the date of the programmed event, <latex>$t_{cur}$</latex> is the current time in the simulator and <latex>$T_{delay}$</latex> the value that must be informed in the output event register.
588                 </para>
589                 <para>
590                     For i.e, suppose that you want generate an event with the first event output port, 1ms after
591                     each calls of the block, then you'll use :
592                 </para>
593                 <programlisting role="c"><![CDATA[
594 #include "scicos_block4.h"
595
596 ...
597
598 void mycomputfunc(scicos_block *block,int flag)
599 {
600 ...
601     if (flag==3) {
602         block->evout[0]=0.001;
603     }
604 ...
605 }
606
607 ]]></programlisting>
608                 <para> 
609                     Note that every events generated from output event register will be asynchronous with event coming from event input port (even if you set 
610                     <literal>block-&gt;evout[x]=0</literal>). 
611                 </para>
612                 <para>
613                     The event output register must be only written for 
614                     <literal>flag=3</literal>.
615                 </para>
616             </listitem>
617         </itemizedlist>
618         <para>
619             
620         </para>
621     </refsection>
622     <refsection id="Parameters_C_struct">
623         <title>Arguments</title>
624         <para>
625             
626         </para>
627         <itemizedlist>
628             <listitem>
629                 <para>
630                     <emphasis role="bold">block-&gt;nrpar :</emphasis> Integer that gives the length of the real parameter register.
631                 </para>
632                 <para>
633                      One can't override the index <literal>(block-&gt;nrpar)-1</literal> when reading value of real parameters in the register <literal>rpar</literal>.
634                 </para>
635                 <para>
636                      The total number of real parameters can also be got by the use of the C macro <literal>rpar</literal>. 
637                 </para>
638             </listitem>
639             <listitem>
640                 <para>
641                     <emphasis role="bold">block-&gt;rpar :</emphasis> Array of double of size [nrpar,1] corresponding to the real parameter register. That register is used to pass real parameters coming from the Scilab/Xcos environment to your block model.
642                 </para>
643                 <para> The C type of that array is (or C scicos type ).</para>
644                 <para>
645                     Suppose that you have defined the following real parameters in the<link linkend="scicos_model">scicos_model</link> of a block :
646                 </para>
647                 <programlisting role="scilab"><![CDATA[
648 model = scicos_model();
649 model.rpar   = [%pi;%pi/2;%pi/4];
650                     ]]></programlisting>
651                 <para>
652                     you can retrieve the previous data in the C computational function with :
653                 </para>
654                 <programlisting role="c"><![CDATA[
655 #include "scicos_block4.h"
656
657 ...
658
659 double PI;
660 double PI_2;
661 double PI_4;
662
663 ...
664
665 void mycomputfunc(scicos_block *block,int flag)
666 {
667 ...
668     /*get the first value of the real param register*/
669     PI = block->rpar[0];
670     /*get the second value of the real param register*/
671     PI_2 = block->rpar[1];
672     /*get the third value of the real param register*/
673     PI_4 = block->rpar[2];
674 ...
675
676                     ]]></programlisting>
677                 <para>
678                     
679                     You can also use the C macro <literal>GetRparPtrs(block)</literal> to get the pointer of the
680                     real parameter register. For i.e., if we define the following
681                     <link linkend="scicos_model">scicos_model</link>
682                     in an interfacing function of a
683                     scicos block :
684                     
685                 </para>
686                 <programlisting role="code"><![CDATA[
687 A = [1.3 ; 4.5 ; 7.9 ; 9.8];
688 B = [0.1 ; 0.98];
689 model = scicos_model();
690
691 model.rpar   = [A;B] 
692                     ]]></programlisting>
693                 <para>
694                     in the corresponding C computational function of that block, we'll use :
695                 </para>
696                 <programlisting role="c"><![CDATA[
697 #include "scicos_block4.h"
698
699 ...
700
701 double *rpar;
702 double *A;
703 double *B;
704
705 ...
706
707 void mycomputfunc(scicos_block *block,int flag)
708 {
709 ...
710     /*get ptrs of the real param register*/
711     rpar = GetRparPtrs(block);
712     /*get the A ptrs array*/
713     A = rpar;
714     /*get the B ptrs array*/
715     B = &rpar[4];
716     /*or B = rpar + 4;*/
717 ...
718 }
719                 ]]></programlisting>
720                 <para>
721                     Note that real parameters register is only accessible for reading.
722                 </para>
723             </listitem>
724             <listitem>
725                 <para>
726                     <emphasis role="bold">block-&gt;nipar :</emphasis> Integer that gives the length of the integer parameter register.
727                 </para>
728                 <para>
729                      One can't override the index <literal>(block-&gt;nipar)-1</literal> when reading value of integer parameters in the register <literal>ipar</literal>.
730                 </para>
731                 <para>
732                      The total number of integer parameters can also be got by the use of the C macro <literal>GetNipar(block)</literal>. 
733                 </para>
734             </listitem>
735             <listitem>
736                 <para>
737                     <emphasis role="bold">block-&gt;ipar :</emphasis> Array of int of size nipar,1 corresponding to the integer parameter register. That register is used to pass integer parameters coming from the Scilab/Xcos environment to your block model.
738                 </para>
739                 <para>
740                     The C type of that array is <literal>int*</literal> (or C scicos type <literal>SCSINT_COP *</literal>).
741                 </para>
742                 <para>
743                     Suppose that you have defined the following integer parameters in the<link linkend="scicos_model">scicos_model</link> of a block :
744                 </para>
745                 <programlisting role="scilab"><![CDATA[
746 model = scicos_model();
747 model.ipar = [(1:3)';5] 
748                     ]]></programlisting>
749                 <para>
750                     you can retrieve the previous data in the C computational function with :
751                 </para>
752                 <programlisting role="c"><![CDATA[
753 #include "scicos_block4.h"
754
755 ...
756
757 int one;
758 int two;
759 int three;
760 int five;
761
762 ...
763
764 void mycomputfunc(scicos_block *block,int flag)
765 {
766 ...
767     /*get the first value of the integer param register*/
768     one = block->ipar[0];
769     /*get the second value of the integer param register*/
770     two = block->ipar[1];
771     /*get the third value of the integer param register*/
772     three = block->ipar[2];
773     /*get the fourth value of the integer param register*/
774     five = block->ipar[3];
775 ...
776 }
777                     ]]></programlisting>
778                 <para>
779                     You can also use the C macro <literal>GetIparPtrs(block)</literal> to get the pointer of the integer parameter register.
780                 </para>
781                 <para>
782                     Most of time in the scicos C block libraries, the integer register is used to parametrize the length of real parameters. For i.e. if you define the following <link linkend="scicos_model">scicos_model</link> in a block :
783                 </para>
784                 <programlisting role="scilab"><![CDATA[
785 // set a random size for the first real parameters
786 A_sz = int(rand(10)*10);
787 // set a random size for the second real parameters
788 B_sz = int(rand(10)*10);
789 // set the first real parameters
790 A = rand(A_sz,1,``uniform'');
791 // set the second real parameters
792 B = rand(B_sz,1,``normal'');
793
794 model = scicos_model();
795 // set ipar
796 model.ipar = [A_sz;B_sz]
797 // set rpar (length of A_sz+B_sz)
798 model.rpar = [A;B]
799 ]]></programlisting>
800                 <para>
801                     the array of real parameters (parametrized by <literal>ipar</literal>) can be retrieved in the correspondig C computational function with :
802                 </para>
803                 <programlisting role="c"><![CDATA[
804 #include "scicos_block4.h"
805
806 ...
807 int A_sz;
808 int B_sz;
809 double *rpar;
810 double *A;
811 double *B;
812 double cumsum;
813 int i; 
814 ...
815
816 void mycomputfunc(scicos_block *block,int flag)
817 {
818 ...
819     /*get ptrs of the real param register*/
820     rpar = GetRparPtrs(block);
821     /*get size of the first real param register*/
822     A_sz = block->ipar[0];
823     /*get size of the second real param register*/
824     B_sz = block->ipar[1];
825     /*get the A ptrs array*/
826     A = rpar;
827     /*get the B ptrs array*/
828     B = &rpar[A_sz];
829
830     /*compute the cumsum of the first real parameter array*/
831     cumsum = 0;
832     for(i=0;i<A_sz;i++) {
833         cumsum += A[i];
834     }
835
836     /*compute the cumsum of the second real parameter array*/
837     cumsum = 0;
838     for(i=0;i<B_sz;i++) {
839         cumsum += B[i];
840     }
841 ...
842 }
843 ]]></programlisting>
844                 <para>
845                     Note that integer parameters register is only accessible for reading.
846                 </para>
847             </listitem>
848             <listitem>
849                 <para>
850                     <emphasis role="bold">block-&gt;nopar :</emphasis> Integer that gives the number of the object parameters.
851                 </para>
852                 <para>
853                      One can't override the index <literal>block-&gt;nopar-1</literal> when accessing data in the arrays <literal>oparsz</literal>, <literal>opartyp</literal>and <literal>oparptr</literal> in a C computational function.
854                 </para>
855                 <para>
856                      This value is also accessible via the C macro <literal>GetNopar(block)</literal>.
857                 </para>
858             </listitem>
859             <listitem>
860                 <para>
861                     <emphasis role="bold">block-&gt;oparsz :</emphasis> An array of integer of size [nopar,2] that contains the dimensions of matrices of object parameters.
862                 </para>
863                 <para> The first column is for the first dimension and the second for the second dimension. For i.e. if we want the dimensions of the last object parameters, we'll use the instructions :
864                 </para>
865                 <programlisting role="c"><![CDATA[
866 #include "scicos_block4.h"
867
868 int nopar;
869 int n,m;
870
871 void mycomputfunc(scicos_block *block,int flag)
872 {
873 ...
874     /*get the number of object parameter*/
875     nopar=block>nopar;
876     
877     ...
878     
879     /*get number of row of the last object parameter*/
880     n=block>oparsz[nopar-1];
881     /*get number of column of the last object parameter*/
882     m=block>oparsz[2*nopar-1];
883 ...
884
885 ]]></programlisting>
886                 <para>
887                     The dimensions of object parameters can be get with the following C macros <literal>GetOparSize(block,x,1)</literal> to get the first dimension of <literal>opar</literal> and <literal>GetOparSize(block,x,2)</literal>to get the second dimension with <literal>x</literal> an integer that gives the index of the object parameter, <emphasis role="bold">numbered from 1 to nopar</emphasis>.
888                 </para>
889             </listitem>
890             <listitem>
891                 <para>
892                     <emphasis role="bold">block-&gt;opartyp :</emphasis> An array of integer of size [nopar,1] that contains the type of matrices of object parameters.
893                 </para>
894                 <para>
895                      The following table gives the correspondence for Scicos/Xcos type expressed in Scilab number, in C number and also corresponding C pointers and C macros used for <literal>oparptr</literal>:
896                 </para>
897                 <informaltable>
898                     <tr>
899                         <td colspan="2">Scilab</td><td colspan="3">C</td>
900                     </tr>
901                     <tr>
902                         <td>Type</td><td>Number</td><td>Number</td><td>Type</td><td>Macros</td>
903                     </tr>
904                     <tr>
905                         <td>Real</td><td>1</td><td>10</td><td>double</td><td>SCSREAL_OP</td>
906                     </tr>
907                     <tr>
908                         <td>complex</td><td>2</td><td>11</td><td>double</td><td>SCSCOMPLEX_COP</td>
909                     </tr>
910                     <tr>
911                         <td>int32</td><td>3</td><td>84</td><td>long</td><td>SCSINT32_OP</td>
912                     </tr>
913                     <tr>
914                         <td>int16</td><td>4</td><td>82</td><td>short</td><td>SCSINT16_OP</td>
915                     </tr>
916                     <tr>
917                         <td>int8</td><td>5</td><td>81</td><td>char</td><td>SCSINT8_OP</td>
918                     </tr>
919                     <tr>
920                         <td>uint32</td><td>6</td><td>814</td><td>unsigned long</td><td>SCSUINT32_OP</td>
921                     </tr>
922                     <tr>
923                         <td>uint16</td><td>7</td><td>812</td><td>unsigned short</td><td>SCSUINT16_OP</td>
924                     </tr>
925                     <tr>
926                         <td>uint8</td><td>8</td><td>811</td><td>unsigned char</td><td>SCSUINT8_OP</td>
927                     </tr>
928                     <tr>
929                         <td>all other data</td><td></td><td>-1</td><td>double</td><td>SCSUNKNOWN_COP</td>
930                     </tr>
931                 </informaltable>
932                 <para>
933                     The type of object parameter can also be got by the use of the C macro <literal>GetOparType(block,x)</literal>. For i.e, if we want the C number type of the first object parameter, we'll use the following C instructions:
934                 </para>
935                 <programlisting role="c"><![CDATA[
936 #include "scicos_block4.h"
937
938 ...
939
940 int opartyp_1;
941 ...
942
943 void mycomputfunc(scicos_block *block,int flag)
944 {
945 ...
946     /*get the number type of the first object parameter*/
947     opartyp_1 = GetOparType(block,1);
948 ...
949 }
950 ]]></programlisting>
951                 <para>
952                 </para>
953             </listitem>
954             <listitem>
955                 <para>
956                     <emphasis role="bold">block-&gt;oparptr :</emphasis> An array of pointers of size [nopar,1] that allow to a direct access to the data contained in the object parameter.
957                 </para>
958                 <para>
959                     Suppose that you have defined in the editor a block with the following<emphasis role="bold">opar</emphasis> field in<link linkend="scicos_model">scicos_model</link> :
960                 </para>
961                 <programlisting role="scilab"><![CDATA[
962 model = scicos_model();
963 model.opar=list( ..
964     int32([1,2;3,4]), ..
965     [1+%i %i 0.5], ..
966     int8([ascii("me") 0]) ..
967 );]]></programlisting>
968                 <para>
969                     Then we have three object parameters, one is an 32-bit integer matrix with two rows and two columns, the second is a vector of complex numbers that can be understand as a matrix of size [1,3] and the third is a string encoded as a standard C one (ASCII ended with a '\0').
970                 </para>
971                 <para>
972                     At the C computational function level, the instructions <literal>block-&gt;oparsz[0]</literal>, <literal>block-&gt;oparsz[1]</literal>, <literal>block-&gt;oparsz[2]</literal>, <literal>block-&gt;oparsz[3]</literal>, <literal>block-&gt;oparsz[4]</literal>, <literal>block-&gt;oparsz[5]</literal> will respectively return the values <literal>2, 1, 1, 2, 3, 3</literal> and the instructions <literal>block-&gt;opartyp[0]</literal>, <literal>block-&gt;opartyp[1]</literal>, <literal>block-&gt;opartyp[2]</literal> the values <literal>11, 84, 81</literal>.
973                 </para>
974                 <para>
975                     <literal>block-&gt;oparptr</literal> will contain then three pointers, and should be viewed as arrays contained data of object parameter as shown in the following figure :
976                 </para>
977                 <mediaobject>
978                     <imageobject>
979                         <imagedata fileref="../../../images/programming_scicos_blocks/c_computational_functions/en_US/C_struct_img9_en_US.gif"/>
980                     </imageobject>
981                     <textobject>
982                         <programlisting role="pic"><![CDATA[
983 .PS
984 down;
985 Oparptr0ptr: box "long*";Oparptr1ptr: box "double*";Oparptr2ptr: box "char*";
986
987 Oparptr0: box "1" at Oparptr0ptr.e + (2.0, 3.0);box "2";box "3";box "4";
988 move;
989 Oparptr1: box "1"; box "0"; box "0.5"; box "1";box "1"; box "0";
990 move;
991 Oparptr2: box "115 'm'"; box "116 'e'"; box "0 '\0'";
992
993 right;
994 line at Oparptr0ptr.e; arc; line; line; line; arc cw; arrow;
995 line at Oparptr1ptr.e; line; arrow;
996 line at Oparptr2ptr.e; arc cw; line; line; line; arc; arrow;
997
998 {"oparptr" at Oparptr0ptr.n + (0, 0.2);}
999 {"oparptr[0]" at Oparptr0 .n + (0, 0.2);}
1000 {"oparptr[1]" at Oparptr1 .n + (0, 0.2);}
1001 {"oparptr[2]" at Oparptr2 .n + (0, 0.2);}
1002
1003 "oparptr[0][0]" ljust at Oparptr0.e + (0.1, 0);
1004 "oparptr[0][1]" ljust at Oparptr0.e + (0.1, -0.5);
1005 "oparptr[0][2]" ljust at Oparptr0.e + (0.1, -1.0);
1006 "oparptr[0][3]" ljust at Oparptr0.e + (0.1, -1.5);
1007
1008 "oparptr[1][0] - Real part" ljust at Oparptr1.e + (0.1, 0);
1009 "oparptr[1][1] - Real part" ljust at Oparptr1.e + (0.1, -0.5);
1010 "oparptr[1][2] - Real part" ljust at Oparptr1.e + (0.1, -1.0);
1011 "oparptr[1][3] - Imaginary part" ljust at Oparptr1.e + (0.1, -1.5);
1012 "oparptr[1][4] - Imaginary part" ljust at Oparptr1.e + (0.1, -2.0);
1013 "oparptr[1][5] - Imaginary part" ljust at Oparptr1.e + (0.1, -2.5);
1014
1015 "oparptr[2][0]" ljust at Oparptr2.e + (0.1, 0);
1016 "oparptr[2][1]" ljust at Oparptr2.e + (0.1, -0.5);
1017 "oparptr[2][2]" ljust at Oparptr2.e + (0.1, -1.0);
1018 .PE
1019                         ]]></programlisting>
1020                     </textobject>
1021                 </mediaobject>
1022                 <para>For i.e., to directly access to the data, the user can use theses instructions :</para>
1023                 <programlisting role="c"><![CDATA[
1024 #include "scicos_block4.h"
1025
1026 ...
1027 SCSINT32_COP *ptr_i;
1028 SCSINT32_COP cumsum_i;
1029 SCSCOMPLEX_COP *ptr_d;
1030 char* str;
1031 SCSREAL_COP cumsum_d;
1032 ...
1033
1034 void mycomputfunc(scicos_block *block,int flag)
1035 {
1036 ...
1037     /*get the ptrs of an int32 object parameter*/
1038     ptr_i = (SCSINT32_COP *) block->oparptr[0];
1039     /*get the ptrs of a double object parameter*/
1040     ptr_d = (SCSCOMPLEX_COP *) block->oparptr[1];
1041     /*get the string*/
1042     str = (char*) block->oparptr[2];
1043     ...
1044     /*compute the cumsum of the int32 matrix*/
1045     cumsum_i = ptr_i[0]+ptr_i[1]+ptr_i[2]+ptr_i[3]; ...
1046     /*compute the cumsum of the real part of the complex matrix*/
1047     cumsum_d = ptr_d[0]+ptr_d[1]+ptr_d[2];
1048     fprintf(stderr, str);
1049 ...
1050
1051 ]]></programlisting>
1052                 <para>
1053                     One can also use the set of C macros : <literal>GetRealOparPtrs(block,x)</literal>, <literal>GetImagOparPtrs(block,x)</literal>, <literal>Getint8OparPtrs(block,x)</literal>, <literal>Getint16OparPtrs(block,x)</literal>, <literal>Getint32OparPtrs(block,x)</literal>, <literal>Getuint8OparPtrs(block,x)</literal>, <literal>Getuint16OparPtrs(block,x)</literal>, <literal>Getuint32OparPtrs(block,x)</literal> to have the appropriate pointer of the data to handle (<emphasis role="bold">x is numbered from 1 to nopar</emphasis>).
1054                 </para>
1055                 <para>
1056                     For the previous example that gives :
1057                 </para>
1058                 <programlisting role="c"><![CDATA[
1059 #include "scicos_block4.h"
1060
1061 ...
1062 SCSINT32_COP *ptr_i;
1063 SCSREAL_COP *ptr_dr;
1064 SCSREAL_COP *ptr_di;
1065 char* str;
1066 ...
1067
1068 void mycomputfunc(scicos_block *block,int flag)
1069 {
1070 ...
1071     /*get the ptrs of an int32 object parameter*/
1072     ptr_i = Getint32OparPtrs(block,1);
1073     /*get the ptrs of a double object parameter*/
1074     ptr_dr = GetRealOparPtrs(block,2);
1075     ptr_di = GetImagOparPtrs(block,2);
1076     /*get the string*/
1077     str = Getint8OparPtrs(block,3);
1078 ...
1079
1080 ]]></programlisting>
1081                 <para>
1082                     Note that object parameters register is only accessible for reading. 
1083                 </para>
1084             </listitem>
1085         </itemizedlist>
1086         <para>
1087             
1088         </para>
1089     </refsection>
1090     <refsection id="Statesandwork_C_struct">
1091         <title>States and work</title>
1092         <para>
1093             
1094         </para>
1095         <itemizedlist>
1096             <listitem>
1097                 <para>
1098                     <emphasis role="bold">block-&gt;nx :</emphasis> Integer that gives the length of the continus state register.
1099                 </para>
1100                 <para>
1101                      One can't override the index <literal>block-&gt;nx-1</literal> when reading or writing data in the array , or with a C computational function. 
1102                 </para>
1103             </listitem>
1104             <listitem>
1105                 <para>
1106                     <emphasis role="bold">block-&gt;x :</emphasis> Array of double of size [nx,1] corresponding to the continuous state register.
1107                 </para>
1108                 <para> That gives the result of the computation of the state derivative.</para>
1109                 <para> A value of a continuous state is readable (for i.e the first state) with the C instructions :
1110                 </para>
1111                 <programlisting role="c"><![CDATA[
1112 #include "scicos_block4.h"
1113
1114 ...
1115 double x_1;
1116 ...
1117
1118 void mycomputfunc(scicos_block *block,int flag)
1119 {
1120 ...
1121     x_1=block->x[0];
1122 ...
1123
1124 ]]></programlisting>
1125                 <para>
1126                     Note that on <literal>flag=4</literal>, user can write some initial conditions in that register.
1127                 </para>
1128                 <para>
1129                     The pointer of that array can also be retrieve via the C macro <literal>GetState(block)</literal>.
1130                 </para>
1131             </listitem>
1132             <listitem>
1133                 <para>
1134                     <emphasis role="bold">block-&gt;xd :</emphasis> Array of double of size [nx,1] corresponding to the derivative of the continuous state register.
1135                 </para>
1136                 <para>
1137                     When systems are explicitly given in terms of Ordinary Differential Equations (ODE), it can be explicitly expressed or implicitly used in the residual vector <literal>res</literal> when systems are expressed in terms of Differantial Algebraic Equations (DAE).
1138                 </para>
1139                 <para>
1140                      Both systems must be programmed with <literal>flag=0</literal>.
1141                 </para>
1142                 <para>For i.e the Lorenz attractor written as an ODE system with three state variables, of the form :
1143                 </para>
1144                 <latex>
1145                     $$
1146                     \dot{x} = f(x,t)
1147                     $$
1148                 </latex>
1149                 <para>
1150                     will be defined :
1151                 </para>
1152                 <programlisting role="c"><![CDATA[
1153 #include "scicos_block4.h"
1154
1155 ...
1156 /* define parameters */
1157 double a = 10;
1158 double b = 28;
1159 double c = 8/3;
1160 ...
1161
1162 void mycomputfunc(scicos_block *block,int flag)
1163 {
1164 ...
1165     double *x = block->x;
1166     double *xd = block->xd;
1167
1168     if (flag == 0) {
1169         xd[0] = a*(x[1]-x[0]);
1170         xd[1] = x[1]*(b-x[2])-x[1];
1171         xd[2] = x[0]*x[1]-c*x[2];
1172     }
1173 ...
1174
1175 ]]></programlisting>
1176             </listitem>
1177             <listitem>
1178                 <para>
1179                     <emphasis role="bold">block-&gt;res :</emphasis> Array of double of size [nx,1] corresponding to Differential Algebraic Equation (DAE) residual.
1180                 </para>
1181                 <para> It is used to write the vector of systems that have the following form :</para>
1182                 <latex>
1183                     $$
1184                     f(x, \dot{x}, t) = 0
1185                     $$
1186                 </latex>
1187                 <para>  For i.e the Lorenz attractor written as a DAE system with three state variables, will be defined :
1188                 </para>
1189                 <programlisting role="c"><![CDATA[ 
1190 #include "scicos_block4.h"
1191
1192 ...
1193 /* define parameters */
1194 double a = 10;
1195 double b = 28;
1196 double c = 8/3;
1197 ...
1198
1199 void mycomputfunc(scicos_block *block,int flag)
1200 {
1201 ...
1202     double *x = block->x;
1203     double *xd = block->xd;
1204     double *res = block->res;
1205     
1206     if (flag == 0) {
1207         res[0] = - xd[0] + (a*(x[1]-x[0]));
1208         res[1] = - xd[1] + (x[0]*(b-x[2])-x[1]);
1209         res[2] = - xd[2] + (x[0]*x[1]-c*x[2]);
1210     }
1211 ...
1212 }
1213 ]]></programlisting>
1214             </listitem>
1215             <listitem>
1216                 <para>
1217                     <emphasis role="bold">block-&gt;nz :</emphasis> Integer that gives the length of the discrete state register.
1218                 </para>
1219                 <para>
1220                      One can't override the index <literal>block-&gt;nz-1</literal> when reading data in the array <literal>z</literal> with a C computational function.
1221                 </para>
1222                 <para>
1223                      This value is also accessible via the C macros <literal>GetNdstate(block)</literal>. 
1224                 </para>
1225             </listitem>
1226             <listitem>
1227                 <para>
1228                     <emphasis role="bold">block-&gt;z :</emphasis> Array of double of size [nz,1] corresponding to the discrete state register.
1229                 </para>
1230                 <para>A value of a discrete state is directly readable (for i.e the second state) with the C instructions :
1231                 </para>
1232                 <programlisting role="c"><![CDATA[
1233 #include "scicos_block4.h"
1234
1235 ...
1236 double z_2;
1237 ...
1238
1239 void mycomputfunc(scicos_block *block,int flag)
1240 {
1241 ...
1242     z_2=block->z[1];
1243 ...
1244 }
1245 ]]></programlisting>
1246                 <para>
1247                     Note that the state register should be only written for <literal>flag=4</literal> and <literal>flag=2</literal>
1248                 </para>
1249                 <para>
1250                     The pointer of that array can also be retrieve via the C macro <literal>GetDstate(block)</literal>.
1251                 </para>
1252             </listitem>
1253             <listitem>
1254                 <para>
1255                     <emphasis role="bold">block-&gt;noz :</emphasis> Integer that gives the number of the discrete object states.
1256                 </para>
1257                 <para>
1258                     One can't override the index <literal>block-&gt;noz-1</literal> when accessing data in the arrays <literal>ozsz</literal>, <literal>oztyp</literal> and <literal>ozptr</literal> in a C computational function.
1259                 </para>
1260                 <para>
1261                     This value is also accessible via the C macro <literal>GetNoz(block)</literal>. 
1262                 </para>
1263             </listitem>
1264             <listitem>
1265                 <para>
1266                     <emphasis role="bold">block-&gt;ozsz :</emphasis> An array of integer of size [noz,2] that contains the dimensions of matrices of discrete object states.
1267                 </para>
1268                 <para> The first column is for the first dimension and the second for the second dimension. For i.e. if we want the dimensions of the last object state, we'll use the instructions :
1269                 </para>
1270                 <programlisting role="c"><![CDATA[
1271 #include "scicos_block4.h"
1272
1273 ...
1274 int noz;
1275 int n,m;
1276 ...
1277
1278 void mycomputfunc(scicos_block *block,int flag)
1279 {
1280 ...
1281     /*get the number of object state*/
1282     noz=block>noz;
1283     /*get number of row of the last object state*/
1284     n=block>ozsz[noz-1];
1285     /*get number of column of the last object state*/
1286     m=block>ozsz[2*noz-1];
1287 ...
1288
1289 ]]></programlisting>
1290                 <para>
1291                     The dimensions of object discrete states can be get with the following C macro : <literal>GetOzSize(block,x,1)</literal> for the first dimension and <literal>GetOzSize(block,x,2)</literal> for the second dimension with <literal>x</literal> an integer that gives the index of the discrete object state, <emphasis role="bold">numbered from 1 to noz</emphasis>.
1292                 </para>
1293             </listitem>
1294             <listitem>
1295                 <para>
1296                     <emphasis role="bold">block-&gt;oztyp :</emphasis> An array of integer of size [noz,1] that contains the type of matrices of discrete object states.
1297                 </para>
1298                 <para>
1299                      The following table gives the correspondence table for scicos type expressed in Scilab number, in C number and also corresponding C pointers and C macros used for <literal>ozptr</literal>:
1300                 </para>
1301                 <informaltable>
1302                     <tr>
1303                         <td colspan="2">Scilab</td><td colspan="3">C</td>
1304                     </tr>
1305                     <tr>
1306                         <td>Type</td><td>Number</td><td>Number</td><td>Type</td><td>Macros</td>
1307                     </tr>
1308                     <tr>
1309                         <td>Real</td><td>1</td><td>10</td><td>double</td><td>SCSREAL_OP</td>
1310                     </tr>
1311                     <tr>
1312                         <td>complex</td><td>2</td><td>11</td><td>double</td><td>SCSCOMPLEX_COP</td>
1313                     </tr>
1314                     <tr>
1315                         <td>int32</td><td>3</td><td>84</td><td>long</td><td>SCSINT32_OP</td>
1316                     </tr>
1317                     <tr>
1318                         <td>int16</td><td>4</td><td>82</td><td>short</td><td>SCSINT16_OP</td>
1319                     </tr>
1320                     <tr>
1321                         <td>int8</td><td>5</td><td>81</td><td>char</td><td>SCSINT8_OP</td>
1322                     </tr>
1323                     <tr>
1324                         <td>uint32</td><td>6</td><td>814</td><td>unsigned long</td><td>SCSUINT32_OP</td>
1325                     </tr>
1326                     <tr>
1327                         <td>uint16</td><td>7</td><td>812</td><td>unsigned short</td><td>SCSUINT16_OP</td>
1328                     </tr>
1329                     <tr>
1330                         <td>uint8</td><td>8</td><td>811</td><td>unsigned char</td><td>SCSUINT8_OP</td>
1331                     </tr>
1332                     <tr>
1333                         <td>all other data</td><td></td><td>-1</td><td>double</td><td>SCSUNKNOWN_COP</td>
1334                     </tr>
1335                 </informaltable>
1336                 <para>
1337                     The type of discrete object state can also be got by the use of the C macro <literal>GetOzType(block,x)</literal>. For i.e, if we want the C number type of the first discrete object state, we'll use the following C instructions:
1338                 </para>
1339                 <programlisting role="c"><![CDATA[
1340 #include "scicos_block4.h"
1341
1342 ...
1343 int oztyp_1;
1344 ...
1345
1346 void mycomputfunc(scicos_block *block,int flag)
1347 {
1348 ...
1349     /*get the number type of the first object state*/
1350     oztyp_1 = GetOzType(block,1);
1351 ...
1352 }
1353 ]]></programlisting>
1354             </listitem>
1355             <listitem>
1356                 <para>
1357                     <emphasis role="bold">block-&gt;ozptr :</emphasis> An array of pointers of size [noz,1] that allow to a direct access to the data contained in the discrete object state.
1358                 </para>
1359                 <para>
1360                     Suppose that you have defined in the editor a block with the following<emphasis role="bold">odstate</emphasis> field in <link linkend="scicos_model">scicos_model</link> :
1361                 </para>
1362                 <programlisting role="code"><![CDATA[
1363 model = scicos_model();
1364 model.odstate=list(int32([1,2;3,4]),[1+%i %i 0.5]);
1365 ]]></programlisting>
1366                 <para>
1367                     Then we have two discrete object states, one is an 32-bit integer matrix with two rows and two columns and the second is a vector of complex numbers that can be understand as a matrix of size [1,3].
1368                 </para>
1369                 <para>
1370                     At the C computational function level, the instructions <literal>block-&gt;ozsz[0]</literal>, <literal>block-&gt;ozsz[1]</literal>, <literal>block-&gt;ozsz[2]</literal> and <literal>block-&gt;ozsz[3]</literal> will respectively return the values <literal>2,1,2,3</literal> and the instructions <literal>block-&gt;oztyp[0]</literal>, <literal>block-&gt;oztyp[1]</literal> the values <literal>11</literal> and <literal>84</literal>.
1371                 </para>
1372                 <para>
1373                      <literal>block-&gt;ozptr</literal> will then contain two pointers, and should be viewed as arrays contained data of discrete object state as shown in the following figure :
1374                 </para>
1375                 <mediaobject>
1376                     <imageobject>
1377                         <imagedata fileref="../../../images/programming_scicos_blocks/c_computational_functions/en_US/C_struct_img12_en_US.gif"/>
1378                     </imageobject>
1379                     <textobject>
1380                         <programlisting role="pic"><![CDATA[
1381 .PS
1382 down;
1383 Ozptr0ptr: box "long*";Ozptr1ptr: box "double*";
1384
1385 Ozptr0: box "1" at Ozptr0ptr.e + (2.0, 3.0);box "2";box "3";box "4";
1386 move;
1387 Ozptr1: box "1"; box "0"; box "0.5"; box "1";box "1"; box "0";
1388
1389 right;
1390 line at Ozptr0ptr.e; arc; line; line; line; arc cw; arrow;
1391 line at Ozptr1ptr.e; line; arrow;
1392
1393 {"ozptr" at Ozptr0ptr.n + (0, 0.2);}
1394 {"ozptr[0]" at Ozptr0 .n + (0, 0.2);}
1395 {"ozptr[1]" at Ozptr1 .n + (0, 0.2);}
1396
1397 "ozptr[0][0]" ljust at Ozptr0.e + (0.1, 0);
1398 "ozptr[0][1]" ljust at Ozptr0.e + (0.1, -0.5);
1399 "ozptr[0][2]" ljust at Ozptr0.e + (0.1, -1.0);
1400 "ozptr[0][3]" ljust at Ozptr0.e + (0.1, -1.5);
1401
1402 "ozptr[1][0] - Real part" ljust at Ozptr1.e + (0.1, 0);
1403 "ozptr[1][1] - Real part" ljust at Ozptr1.e + (0.1, -0.5);
1404 "ozptr[1][2] - Real part" ljust at Ozptr1.e + (0.1, -1.0);
1405 "ozptr[1][3] - Imaginary part" ljust at Ozptr1.e + (0.1, -1.5);
1406 "ozptr[1][4] - Imaginary part" ljust at Ozptr1.e + (0.1, -2.0);
1407 "ozptr[1][5] - Imaginary part" ljust at Ozptr1.e + (0.1, -2.5);
1408 .PE
1409                         ]]></programlisting>
1410                     </textobject>
1411                 </mediaobject>
1412                 
1413                 <para>For i.e., to directly access to the data, the user can use theses instructions : </para>
1414                 <programlisting role="c"><![CDATA[
1415 #include "scicos_block4.h"
1416
1417 ...
1418 SCSINT32_COP *ptr_i;
1419 SCSINT32_COP cumsum_i;
1420 SCSCOMPLEX_COP *ptr_d;
1421 SCSREAL_COP cumsum_d;
1422 ...
1423
1424 void mycomputfunc(scicos_block *block,int flag)
1425 {
1426 ...
1427     /*get the ptrs of an int32 discrete object state*/
1428     ptr_i = (SCSINT32_COP *) block->ozptr[0];
1429     /*get the ptrs of a double discrete object state*/
1430     ptr_d = (SCSCOMPLEX_COP *) block->ozptr[1];
1431
1432     /*compute the cumsum of the int32 matrix*/
1433     cumsum_i = ptr_i[0]+ptr_i[1]+ptr_i[2]+ptr_i[3];
1434
1435     /*compute the cumsum of the real part of the complex matrix*/
1436     cumsum_d = ptr_d[0]+ptr_d[1]+ptr_d[2];
1437 ...
1438 }
1439 ]]></programlisting>
1440                 <para>
1441                     One can also use the set of C macros : <literal>GetRealOzPtrs(block,x)</literal>, <literal>GetImagOzPtrs(block,x)</literal>, <literal>Getint8OzPtrs(block,x)</literal>, <literal>Getint16OzPtrs(block,x)</literal>, <literal>Getint32OzPtrs(block,x)</literal>, <literal>Getuint8OzPtrs(block,x)</literal>, <literal>Getuint16OzPtrs(block,x)</literal>, <literal>Getuint32OzPtrs(block,x)</literal> to have the appropriate pointer of the data to handle (<emphasis role="bold">x is numbered from 1 to noz</emphasis>).
1442                 </para>
1443                 <para>
1444                     For the previous example that gives :
1445                 </para>
1446                 <programlisting role="c"><![CDATA[
1447  #include "scicos_block4.h"
1448  
1449 ...
1450 SCSINT32_COP *ptr_i;
1451 SCSREAL_COP *ptr_dr;
1452 SCSREAL_COP *ptr_di;
1453 ...
1454
1455 void mycomputfunc(scicos_block *block,int flag)
1456 {
1457 ...
1458     /*get the ptrs of an int32 discrete object state*/
1459     ptr_i = Getint32OzPtrs(block,1);
1460     /*get the ptrs of a double discrete object state*/
1461     ptr_dr = GetRealOzPtrs(block,2);
1462     ptr_di = GetImagOzPtrs(block,2);
1463 ...
1464
1465 ]]></programlisting>
1466                 <para>
1467                     Finally note that the discrete objects state should be only written for <literal>flag=4</literal> and <literal>flag=2</literal>.
1468                 </para>
1469             </listitem>
1470             <listitem>
1471                 <para>
1472                     <emphasis role="bold">block-&gt;work :</emphasis> A free pointer to set a working array for the block.
1473                 </para>
1474                 <para>
1475                     The work pointer must be firstly allocated when <literal>flag=4</literal> and finally be free in the <literal>flag=5</literal>.
1476                 </para>
1477                 <para>Then a basic life cyle of that pointer in a C computational function should be :
1478                 </para>
1479                 <programlisting role="c"><![CDATA[
1480 #include "scicos_block4.h"
1481
1482 ...
1483 void** work=block->work;
1484 ...
1485
1486 void mycomputfunc(scicos_block *block,int flag)
1487 {
1488 ...
1489     switch(flag) {
1490         case 4: /*initialization*/
1491             /*allocation of work*/
1492             if (*work=scicos_malloc(sizeof(double))==NULL) {
1493                 set_block_error(-16);
1494                 return;
1495             }
1496             break;
1497             
1498         case 5: /*finish*/
1499             scicos_free(*work);
1500             break;
1501             
1502         /*other flag treatment*/
1503         ...
1504     }
1505
1506 ...
1507
1508 ]]></programlisting>
1509                 <para>
1510                     Note that if a block use a <literal>work</literal> pointer, it will be called with <literal>flag=2></literal> even if the block do not use discrete states.
1511                 </para>
1512                 <para>
1513                     The pointer of that array can also be retrieve via the C macro <literal>GetWorkPtrs(block)</literal>. 
1514                 </para>
1515             </listitem>
1516         </itemizedlist>
1517         <para>
1518             
1519         </para>
1520     </refsection>
1521     <refsection id="Zerocrossingsurfacesandmodes_C_struct">
1522         <title>Zero crossing surfaces and modes</title>
1523         <para>
1524             
1525         </para>
1526         <itemizedlist>
1527             <listitem>
1528                 <para>
1529                     <emphasis role="bold">block-&gt;ng :</emphasis> Integer that gives the number of zero crossing surface of the block.
1530                 </para>
1531                 <para>
1532                      One can't override the index <literal>(block-&gt;ng)-1</literal> when reading/writing data in the array <literal>g</literal> with a C computational function.
1533                 </para>
1534                 <para>
1535                     The number of zero crossing surface can also be got by the use of the C macro <literal>GetNg(block)</literal>. 
1536                 </para>
1537             </listitem>
1538             <listitem>
1539                 <para>
1540                     <emphasis role="bold">block-&gt;g :</emphasis> Array of double of size [ng,1] corresponding to the zero crossing surface register.
1541                 </para>
1542                 <para>That register is used to detect zero crossing of state variable during time domain integration.</para>
1543                 <para>
1544                     Note that it is accessible for writing for <literal>flag=9</literal>.
1545                 </para>
1546                 <para>
1547                     The pointer of that array can also be retrieve via the C macro <literal>GetGPtrs(block)</literal>. 
1548                 </para>
1549             </listitem>
1550             <listitem>
1551                 <para>
1552                     <emphasis role="bold">block-&gt;nmode :</emphasis> Integer that gives the number of mode of the block.
1553                 </para>
1554                 <para>
1555                     One can't override the index <literal>(block-&gt;mode)-1</literal> when reading/writing data in the array with a C computational function.
1556                 </para>
1557                 <para>
1558                      The number of mode can also be got by the use of the C macro <literal>GetNmode(block)</literal>.
1559                 </para>
1560             </listitem>
1561             <listitem>
1562                 <para>
1563                     <emphasis role="bold">block-&gt;mode :</emphasis> Array of integer of size [nmode,1] corresponding to the mode register.
1564                 </para>
1565                 <para> That register is used to set the mode of state variable during time domain integration.</para>
1566                 <para>
1567                     It is typically accessible for writing for <literal>flag=9</literal>.
1568                 </para>
1569                 <para>
1570                     The pointer of that array can also be retrieve via the C macro <literal>GetModePtrs(block)</literal>. 
1571                 </para>
1572             </listitem>
1573         </itemizedlist>
1574         <para>
1575             
1576         </para>
1577     </refsection>
1578     <refsection id="Miscallaneous_C_struct">
1579         <title>Miscallaneous</title>
1580         <itemizedlist>
1581             <listitem>
1582                 <para>
1583                     <emphasis role="bold">block-&gt;type :</emphasis> Integer that gives the type of the computational function. For C blocks, this number is equal to <literal>4</literal>. 
1584                 </para>
1585             </listitem>
1586             <listitem>
1587                 <para>
1588                     <emphasis role="bold">block-&gt;label :</emphasis> Strings array that allows to retrieve the label of the block.
1589                 </para>
1590             </listitem>
1591             <listitem>
1592                 <para>
1593                     <emphasis role="bold">block-&gt;uid :</emphasis> Strings array that allows to retrieve the uid of the block.
1594                 </para>
1595             </listitem>
1596         </itemizedlist>
1597     </refsection>
1598 </refentry>
1599