1afc820d909d2dd54c7ba68032e43f80934c7211
[scilab.git] / scilab / modules / api_scilab / src / cpp / api_boolean_sparse.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Antoine ELIAS
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  * Please note that piece of code will be rewrited for the Scilab 6 family
12  * However, the API (profile of the functions in the header files) will be
13  * still available and supported in Scilab 6.
14  */
15
16
17 #include "sparse.hxx"
18 #include "gatewaystruct.hxx"
19
20 extern "C"
21 {
22 #include <string.h>
23 #include "sci_malloc.h"
24 #include "api_scilab.h"
25 #include "call_scilab.h"
26 #include "core_math.h"
27 #include "api_internal_common.h"
28 #include "api_boolean_sparse.h"
29 #include "api_internal_boolean_sparse.h"
30 #include "localization.h"
31 }
32
33 using namespace std;
34 using namespace types;
35
36 SciErr getBooleanSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos)
37 {
38     SciErr sciErr = sciErrInit();
39     int iType = 0;
40
41     if (        _piAddress == NULL)
42     {
43         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "getBooleanSparseMatrix");
44         return sciErr;
45     }
46
47     sciErr =  getVarType(_pvCtx, _piAddress, &iType);
48     if (sciErr.iErr || iType != sci_boolean_sparse)
49     {
50         addErrorMessage(&sciErr, API_ERROR_GET_BOOLEAN_SPARSE, _("%s: Unable to get argument #%d"), "getBooleanSparseMatrix", getRhsFromAddress(_pvCtx, _piAddress));
51         return sciErr;
52     }
53
54     sciErr = getVarDimension(_pvCtx, _piAddress, _piRows, _piCols);
55     if (sciErr.iErr)
56     {
57         addErrorMessage(&sciErr, API_ERROR_GET_BOOLEAN_SPARSE, _("%s: Unable to get argument #%d"), "getBooleanSparseMatrix", getRhsFromAddress(_pvCtx, _piAddress));
58         return sciErr;
59     }
60
61     SparseBool* pSpBool = ((InternalType*)_piAddress)->getAs<SparseBool>();
62     *_piNbItem = (int)pSpBool->nbTrue();
63
64     if (_piNbItemRow == NULL)
65     {
66         return sciErr;
67     }
68
69     int* piNbItemRows = (int*)MALLOC(sizeof(int) * *_piRows);
70     *_piNbItemRow = pSpBool->getNbItemByRow(piNbItemRows);
71
72     if (_piColPos == NULL)
73     {
74         return sciErr;
75     }
76
77     int* piColPos = (int*)MALLOC(sizeof(int) * *_piNbItem);
78     *_piColPos = pSpBool->getColPos(piColPos);
79
80     return sciErr;
81 }
82
83 SciErr allocBooleanSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos)
84 {
85     SciErr sciErr = sciErrInit();
86 #if 0
87     int iNewPos = Top - Rhs + _iVar;
88     int iAddr   = *Lstk(iNewPos);
89     int iPos    = 5 + _iRows + _iNbItem;
90     int* piAddr = NULL;
91
92     //return empty matrix
93     if (_iRows == 0 && _iCols == 0)
94     {
95         double dblReal = 0;
96         sciErr = createMatrixOfDouble(_pvCtx, _iVar, 0, 0, &dblReal);
97         if (sciErr.iErr)
98         {
99             addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
100         }
101         return sciErr;
102     }
103
104     int iMemSize = (int)( ( (double)iPos / 2 ) + 0.5);
105     int iFreeSpace = iadr(*Lstk(Bot)) - (iadr(iAddr));
106     if (iMemSize > iFreeSpace)
107     {
108         addStackSizeError(&sciErr, ((StrCtx*)_pvCtx)->pstName, iMemSize);
109         return sciErr;
110     }
111
112     getNewVarAddressFromPosition(_pvCtx, iNewPos, &piAddr);
113     sciErr = fillBooleanSparseMatrix(_pvCtx, piAddr, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos);
114     if (sciErr.iErr)
115     {
116         addErrorMessage(&sciErr, API_ERROR_ALLOC_BOOLEAN_SPARSE, _("%s: Unable to create variable in Scilab memory"), "allocBooleanSparseMatrix");
117         return sciErr;
118     }
119
120     iPos += iAddr;
121     updateInterSCI(_iVar, '$', iAddr, iPos);
122     updateLstk(iNewPos, iPos, 0);
123 #endif
124     return sciErr;
125 }
126
127 SciErr fillBooleanSparseMatrix(void* _pvCtx, int *_piAddress, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos)
128 {
129     SciErr sciErr = sciErrInit();
130     if (_piAddress == NULL)
131     {
132         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "fillBooleanSparseMatrix");
133         return sciErr;
134     }
135
136     _piAddress[0]               = sci_boolean_sparse;
137     _piAddress[1]               = Min(_iRows, _iRows * _iCols);
138     _piAddress[2]               = Min(_iCols, _iRows * _iCols);
139     _piAddress[3]               = 0;
140
141     _piAddress[4]               = _iNbItem;
142
143     *_piNbItemRow       = _piAddress + 5;//4 for header + 1 for NbItem
144     *_piColPos          = *_piNbItemRow + _iRows;
145     return sciErr;
146 }
147
148 SciErr createBooleanSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos)
149 {
150     SciErr sciErr = sciErrInit();
151     int* piNbItemRow    = NULL;
152     int* piColPos       = NULL;
153
154     if (_iRows == 0 && _iCols == 0)
155     {
156         double dblReal = 0;
157         sciErr = createMatrixOfDouble(_pvCtx, _iVar, 0, 0, &dblReal);
158         if (sciErr.iErr)
159         {
160             addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
161         }
162         return sciErr;
163     }
164
165     sciErr = allocBooleanSparseMatrix(_pvCtx, _iVar, _iRows, _iCols, _iNbItem, &piNbItemRow, &piColPos);
166     if (sciErr.iErr)
167     {
168         addErrorMessage(&sciErr, API_ERROR_CREATE_BOOLEAN_SPARSE, _("%s: Unable to create variable in Scilab memory"), "createBooleanSparseMatrix");
169         return sciErr;
170     }
171
172     memcpy(piNbItemRow, _piNbItemRow, _iRows * sizeof(int));
173     memcpy(piColPos, _piColPos, _iNbItem * sizeof(int));
174     return sciErr;
175 }
176
177 SciErr createNamedBooleanSparseMatrix(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos)
178 {
179     SciErr sciErr = sciErrInit();
180 #if 0
181     int iVarID[nsiz];
182     int iSaveRhs        = Rhs;
183     int iSaveTop        = Top;
184     int iPos            = 0;
185
186     int* piAddr         = NULL;
187     int* piNbItemRow    = NULL;
188     int* piColPos       = NULL;
189
190     //return named empty matrix
191     if (_iRows == 0 && _iCols == 0)
192     {
193         double dblReal = 0;
194         sciErr = createNamedMatrixOfDouble(_pvCtx, _pstName, 0, 0, &dblReal);
195         if (sciErr.iErr)
196         {
197             addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createNamedEmptyMatrix");
198         }
199         return sciErr;
200     }
201
202     if (!checkNamedVarFormat(_pvCtx, _pstName))
203     {
204         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createNamedBooleanSparseMatrix", _pstName);
205         return sciErr;
206     }
207
208     C2F(str2name)(_pstName, iVarID, (int)strlen(_pstName));
209     Top = Top + Nbvars + 1;
210
211     int iMemSize = (int)( ( (double)iPos / 2) + 0.5);
212     int iFreeSpace = iadr(*Lstk(Bot)) - (iadr(Top));
213     if (iMemSize > iFreeSpace)
214     {
215         addStackSizeError(&sciErr, ((StrCtx*)_pvCtx)->pstName, iMemSize);
216         return sciErr;
217     }
218
219     getNewVarAddressFromPosition(_pvCtx, Top, &piAddr);
220     sciErr = fillBooleanSparseMatrix(_pvCtx, piAddr, _iRows, _iCols, _iNbItem, &piNbItemRow, &piColPos);
221     if (sciErr.iErr)
222     {
223         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_BOOLEAN_SPARSE, _("%s: Unable to create %s named \"%s\""), "createNamedBooleanSparseMatrix", _("boolean sparse matrix"), _pstName);
224         return sciErr;
225     }
226
227     memcpy(piNbItemRow, _piNbItemRow, _iRows * sizeof(int));
228     memcpy(piColPos, _piColPos, _iNbItem * sizeof(int));
229
230     iPos        = 5;//4 for header + 1 for NbItem
231     iPos += _iRows + _iNbItem;
232
233     //update "variable index"
234     updateLstk(Top, *Lstk(Top) + iPos, 0);
235
236     Rhs = 0;
237     //Add name in stack reference list
238     createNamedVariable(iVarID);
239
240     Top = iSaveTop;
241     Rhs = iSaveRhs;
242 #endif
243
244     return sciErr;
245 }
246
247 SciErr readNamedBooleanSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int* _piNbItemRow, int* _piColPos)
248 {
249     SciErr sciErr       = sciErrInit();
250     int* piAddr         = NULL;
251     int* piNbItemRow    = 0;
252     int* piColPos       = 0;
253
254     sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
255     if (sciErr.iErr)
256     {
257         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_BOOLEAN_SPARSE, _("%s: Unable to get variable \"%s\""), "readNamedBooleanSparseMatrix", _pstName);
258         return sciErr;
259     }
260
261     sciErr = getBooleanSparseMatrix(_pvCtx, piAddr, _piRows, _piCols, _piNbItem, &piNbItemRow, &piColPos);
262     if (sciErr.iErr)
263     {
264         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_BOOLEAN_SPARSE, _("API_ERROR_READ_NAMED_BOOLEAN_SPARSE"));
265         return sciErr;
266     }
267
268     if (_piNbItemRow == NULL)
269     {
270         return sciErr;
271     }
272
273     memcpy(_piNbItemRow, piNbItemRow, *_piRows * sizeof(int));
274
275     if (_piColPos == NULL)
276     {
277         return sciErr;
278     }
279
280     memcpy(_piColPos, piColPos, *_piNbItem * sizeof(int));
281     return sciErr;
282 }
283 /*--------------------------------------------------------------------------*/
284 int isBooleanSparseType(void* _pvCtx, int* _piAddress)
285 {
286     return checkVarType(_pvCtx, _piAddress, sci_boolean_sparse);
287 }
288 /*--------------------------------------------------------------------------*/
289 int isNamedBooleanSparseType(void* _pvCtx, const char* _pstName)
290 {
291     return checkNamedVarType(_pvCtx, _pstName, sci_boolean_sparse);
292 }
293 /*--------------------------------------------------------------------------*/
294 int getAllocatedBooleanSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos)
295 {
296     SciErr sciErr = sciErrInit();
297     int* piNbItemRow    = NULL;
298     int* piColPos                       = NULL;
299
300     sciErr = getBooleanSparseMatrix(_pvCtx, _piAddress, _piRows, _piCols, _piNbItem, &piNbItemRow, &piColPos);
301     if (sciErr.iErr)
302     {
303         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_BOOLEAN_SPARSE, _("%s: Unable to get argument #%d"), "getAllocatedBooleanSparseMatrix", getRhsFromAddress(_pvCtx, _piAddress));
304         printError(&sciErr, 0);
305         return sciErr.iErr;
306     }
307
308     *_piNbItemRow               = (int*)MALLOC(sizeof(int) * *_piRows);
309     memcpy(*_piNbItemRow, piNbItemRow, sizeof(int) * *_piRows);
310
311     *_piColPos                  = (int*)MALLOC(sizeof(int) * *_piNbItem);
312     memcpy(*_piColPos, piColPos, sizeof(int) * *_piNbItem);
313
314     return 0;
315 }
316 /*--------------------------------------------------------------------------*/
317 int getNamedAllocatedBooleanSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos)
318 {
319     SciErr sciErr = sciErrInit();
320     sciErr = readNamedBooleanSparseMatrix(_pvCtx, _pstName, _piRows, _piCols, _piNbItem, NULL, NULL);
321     if (sciErr.iErr)
322     {
323         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_ALLOC_BOOLEAN_SPARSE, _("%s: Unable to get argument \"%s\""), "getNamedAllocatedBooleanSparseMatrix", _pstName);
324         printError(&sciErr, 0);
325         return sciErr.iErr;
326     }
327
328     *_piNbItemRow               = (int*)MALLOC(sizeof(int) * *_piRows);
329     *_piColPos                  = (int*)MALLOC(sizeof(int) * *_piNbItem);
330
331     sciErr = readNamedBooleanSparseMatrix(_pvCtx, _pstName, _piRows, _piCols, _piNbItem, *_piNbItemRow, *_piColPos);
332     if (sciErr.iErr)
333     {
334         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_ALLOC_BOOLEAN_SPARSE, _("%s: Unable to get argument \"%s\""), "getNamedAllocatedBooleanSparseMatrix", _pstName);
335         printError(&sciErr, 0);
336         return sciErr.iErr;
337     }
338
339     return 0;
340 }
341 /*--------------------------------------------------------------------------*/
342 void freeAllocatedBooleanSparse(int* _piNbItemRow, int* _piColPos)
343 {
344     FREE(_piNbItemRow);
345     FREE(_piColPos);
346 }