Scilab Home page | Wiki | Bug tracker | Forge | Mailing list archives | ATOMS | File exchange
Change language to: English - Português - 日本語

Aide Scilab >> API Scilab > Scilab Gateway API > How to > How to access a matrix

# How to access a matrix

How to access a matrix using the C gateway functions

### Description

WARNING: This API is deprecated from Scilab 5.2.0 and is going to be removed with Scilab 6.0. Please use API Scilab (the new Scilab API).

The goal is to get a matrix of doubles send to a function written in C.

For this, we will wrote a C gateway function in which we will retrieve the matrix, we will perform some simple steps in this C function:

• First, we will get an access to the matrix in the Scilab memory

• We will perform some simple operations on the matrix (in this example, we will multiply by 2 each elements of the matrix)

• We will return the result to Scilab

This example is available in the directory SCI/modules/core/examples/ex1.

### The C function

```#include <stack-c.h>

int sci_multiply_by_two(char * fname)
{
int m_in_var, n_in_var, l_in_var;
int m_out_var, n_out_var, l_out_var;
int i_row, j_col;
double * pMatrix = NULL;

GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &m_in_var, &n_in_var, &l_in_var);

// Create the returned variable (a matrix of doubles)
m_out_var = m_in_var;
n_out_var = n_in_var;
CreateVar(2, MATRIX_OF_DOUBLE_DATATYPE, &m_out_var, &n_out_var, &l_out_var);

pMatrix = stk(l_in_var);

// Perform some simple operations on the matrix
for(i_row=0; i_row<m_in_var; i_row++)
{
for(j_col=0; j_col<n_in_var; j_col++)
{
pMatrix[i_row + j_col * m_out_var] = 2 * pMatrix[i_row + j_col * m_in_var];
}
}

// Return the output variable
LhsVar(1) = 2;

return 0;
}```

This file must be saved as "multiply_by_two.c".

The main thing to highlight is that, to build a C gateway function, we need to include the header stack-c.h. In this header, we find the prototypes and macros of the main C gateway functions.

To be able to build and link such a C function to scilab, we need to write a Scilab script which will compile this C function and then create a loader script which will link the C function to a Scilab function.

### The builder script

```// This is the builder.sce
// must be run from this directory

lines(0);

ilib_name  = 'lib_multiply_by_two';

files = ['multiply_by_two.c'];

libs  = [];

table =['multiply_by_two', 'sci_multiply_by_two'];

ldflags = "";
cflags  = "";
fflags  = "";

ilib_build(ilib_name,table,files,libs,'Makelib',ldflags,cflags,fflags);```

This file must be saved as "builder.sce".

This script will tell Scilab which files must be compiled (here, it's multiply_by_two.c), what will be the name of the shared library (here, it's lib_multiply_by_two) and which C symbol will be linked to a Scilab function (here, we will link the sci_multiply_by_two C symbol to the Scilab function "multiply_by_two").

To build this function, we just need to to:

`exec builder.sce;`

Now we are able to test our new C function. First, let's load this new function in scilab:

`exec loader.sce;`

The script loader.sce is normally automatically built by builder.sce.

### Testing our new function

We now write a simple example to test our new function.

```A = [1 2 3 4 5; 6 7 8 9 10; 11 12 13 14 15];

B = multiply_by_two(A);

disp(B);```

The script must be saved as "test.sce".

Let's run our scripts and see what is the result:

```-->exec builder.sce;
Generate a gateway file
Generate a Makefile
ilib_gen_Make: Copy compilation files (Makefile*, libtool...) to TMPDIR
ilib_gen_Make: Copy multiply_by_two.c to TMPDIR
ilib_gen_Make: Copy lib_multiply_by_two.c to TMPDIR
ilib_gen_Make: Modification of the Makefile in TMPDIR.
Running the makefile

-->exec test.sce;

2.     4.     6.     8.     10.
12.    14.    16.    18.    20.
22.    24.    26.    28.    30.
-->```

This simple function has produced a new matrix which corresponds to the matrix transmitted as an input argument and for which each element of the matrix has been multiplied by 2.

### Rebuilding a gateway function

Let's imagine that our gateway function has already been build and we would like to make some changes in our function (multiply by 3 instead of 2).

How do we perform such a changes without restarting Scilab ?

First, we need to list all the dynamic libraries which has been loaded into Scilab. The can be done using the link('show') function:

```-->link('show')
Number of entry points 1.
Shared libraries :
[ 0 ] : 1 libraries.
Entry point lib_multiply_by_two in shared library 0.
ans  =

0.```

Here, in our current Scilab session, only 1 dynamic library has been loaded. This library has a reference number. For our library, it's "0". Now that we know the reference number of our library, we are able to:

• unload this library (using the function ulink(0) - 0 is the reference number of our library)

• perform some modification in the source code of our C gateway function (replace multiply by 2 by 3)

• rebuild the C gateway function (exec builder.sce;)

This is what is done is the following example:

```-->ulink(0)

-->exec builder.sce;
Generate a gateway file
Generate a Makefile
ilib_gen_Make: Copy compilation files (Makefile*, libtool...) to TMPDIR
ilib_gen_Make: Copy multiply_by_two.c to TMPDIR
ilib_gen_Make: Copy lib_multiply_by_two.c to TMPDIR
ilib_gen_Make: Modification of the Makefile in TMPDIR.
Running the makefile

-->exec test.sce;

3.     6.     9.     12.    15.
18.    21.    24.    27.    30.
33.    36.    39.    42.    45.```

• GetRhsVar — a C gateway function which allows to access an argument transmitted to a Scilab function
• Scilab C Types — the C types available in a C gateway
• CreateVar — a C gateway function which allows to create a new Scilab parameter
• LhsVar — a C gateway function which specifies which parameters created inside the C gateway will be returned as an output argument into Scilab.
• stk — Return a pointer to a double to access data stored at a given position in the Scilab memory
• ilib_build — utility for shared library management
{"ft_lang_label":"__label__en","ft_lang_prob":0.74886477,"math_prob":0.6651441,"size":6199,"snap":"2021-43-2021-49","text_gpt3_token_len":1650,"char_repetition_ratio":0.151251,"word_repetition_ratio":0.11485148,"special_character_ratio":0.26826906,"punctuation_ratio":0.16721311,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.99582714,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-10-19T02:03:26Z\",\"WARC-Record-ID\":\"<urn:uuid:02e831bb-0f34-4112-acbe-16e59669d4d5>\",\"Content-Length\":\"46437\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:134119c2-4509-4fdf-8b1f-c90c4b7d9f47>\",\"WARC-Concurrent-To\":\"<urn:uuid:1ea31191-6692-49ff-a960-615649de27af>\",\"WARC-IP-Address\":\"176.9.3.186\",\"WARC-Target-URI\":\"https://help.scilab.org/docs/5.3.1/fr_FR/HowToAccessAMatrix_1.html\",\"WARC-Payload-Digest\":\"sha1:RUCTOZSMEFRJEIJMA6HGEB7XQQMY74N5\",\"WARC-Block-Digest\":\"sha1:YWPMWMZOUM5RCL7YLYXOODBEQS74W7YP\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-43/CC-MAIN-2021-43_segments_1634323585231.62_warc_CC-MAIN-20211019012407-20211019042407-00614.warc.gz\"}"}