2e9fa1e2319d45e7f3d81f3c8218eaeb7fee382f
[scilab.git] / scilab / modules / api_scilab / src / cpp / api_stack_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  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  * Please note that piece of code will be rewrited for the Scilab 6 family
15  * However, the API (profile of the functions in the header files) will be
16  * still available and supported in Scilab 6.
17  */
18
19 #include "sparse.hxx"
20 #include "context.hxx"
21 #include "gatewaystruct.hxx"
22
23 extern "C"
24 {
25 #include <string.h>
26 #include "sci_malloc.h"
27 #include "api_scilab.h"
28 #include "call_scilab.h"
29 #include "core_math.h"
30 #include "api_internal_common.h"
31 #include "api_stack_boolean_sparse.h"
32 #include "api_internal_boolean_sparse.h"
33 #include "localization.h"
34 }
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     types::SparseBool* pSpBool = ((types::InternalType*)_piAddress)->getAs<types::SparseBool>();
62     *_piNbItem = (int)pSpBool->nbTrue();
63
64     if (!sciErr.iErr && _piNbItemRow != NULL)
65     {
66         int* piNbItemRows = (int*)MALLOC(sizeof(int) **_piRows);
67         *_piNbItemRow = pSpBool->getNbItemByRow(piNbItemRows);
68     }
69     if (!sciErr.iErr && _piColPos != NULL)
70     {
71         int* piColPos = (int*)MALLOC(sizeof(int) **_piNbItem);
72         *_piColPos = pSpBool->getColPos(piColPos);
73     }
74
75     return sciErr;
76 }
77
78 SciErr allocBooleanSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos)
79 {
80     SciErr sciErr = sciErrInit();
81     // We cant rewrite this function in Scilab 6
82     // because sparses are not stored like scilab 5.
83     // We cant return pointer to _piNbItemRow and
84     // _piColPos and let user fill it.
85     return sciErr;
86 }
87
88 SciErr fillBooleanSparseMatrix(void* _pvCtx, int* _piAddress, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos)
89 {
90     SciErr sciErr = sciErrInit();
91
92     if (_piAddress == NULL)
93     {
94         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "fillBooleanSparseMatrix");
95         return sciErr;
96     }
97
98     types::SparseBool* pSparse = (types::SparseBool*)_piAddress;
99
100     for (int i = 0; i < _iRows; i++)
101     {
102         for (int j = 0; j < _piNbItemRow[i]; j++)
103         {
104             int iIndex = (*_piColPos++ - 1) * _iRows + i;
105             pSparse->set(iIndex, true);
106         }
107     }
108
109     return sciErr;
110 }
111
112 SciErr createBooleanSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos)
113 {
114     SciErr sciErr = sciErrInit();
115
116     if (_iRows == 0 && _iCols == 0)
117     {
118         double dblReal = 0;
119         sciErr = createMatrixOfDouble(_pvCtx, _iVar, 0, 0, &dblReal);
120         if (sciErr.iErr)
121         {
122             addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
123         }
124         return sciErr;
125     }
126
127     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
128     types::InternalType** out = pStr->m_pOut;
129
130     types::SparseBool* pSparse = new types::SparseBool(_iRows, _iCols);
131     if (pSparse == NULL)
132     {
133         addErrorMessage(&sciErr, API_ERROR_CREATE_BOOLEAN_SPARSE, _("%s: Unable to create variable in Scilab memory"), "createBooleanSparseMatrix");
134         return sciErr;
135     }
136
137     int rhs = _iVar - *getNbInputArgument(_pvCtx);
138     out[rhs - 1] = pSparse;
139
140     sciErr = fillBooleanSparseMatrix(_pvCtx, (int*)pSparse, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos);
141     return sciErr;
142 }
143
144 SciErr createNamedBooleanSparseMatrix(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos)
145 {
146     SciErr sciErr = sciErrInit();
147
148     // check variable name
149     if (checkNamedVarFormat(_pvCtx, _pstName) == 0)
150     {
151         addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Invalid variable name: %s."), "createNamedMatrixOfBoolean", _pstName);
152         return sciErr;
153     }
154
155     //return named empty matrix
156     if (_iRows == 0 && _iCols == 0)
157     {
158         double dblReal = 0;
159         sciErr = createNamedMatrixOfDouble(_pvCtx, _pstName, 0, 0, &dblReal);
160         if (sciErr.iErr)
161         {
162             addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createNamedEmptyMatrix");
163         }
164         return sciErr;
165     }
166
167     if (!checkNamedVarFormat(_pvCtx, _pstName))
168     {
169         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createNamedBooleanSparseMatrix", _pstName);
170         return sciErr;
171     }
172
173     types::SparseBool* pSparse = new types::SparseBool(_iRows, _iCols);
174     if (pSparse == NULL)
175     {
176         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_BOOLEAN_SPARSE, _("%s: Unable to create %s named \"%s\""), "createNamedBooleanSparseMatrix", _("boolean sparse matrix"), _pstName);
177         return sciErr;
178     }
179
180     sciErr = fillBooleanSparseMatrix(_pvCtx, (int*)pSparse, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos);
181
182     wchar_t* pwstName = to_wide_string(_pstName);
183     symbol::Context* ctx = symbol::Context::getInstance();
184     symbol::Symbol sym = symbol::Symbol(pwstName);
185     FREE(pwstName);
186     if (ctx->isprotected(sym) == false)
187     {
188         ctx->put(sym, pSparse);
189     }
190     else
191     {
192         delete pSparse;
193         addErrorMessage(&sciErr, API_ERROR_REDEFINE_PERMANENT_VAR, _("Redefining permanent variable.\n"));
194     }
195     return sciErr;
196 }
197
198 SciErr readNamedBooleanSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int* _piNbItemRow, int* _piColPos)
199 {
200     SciErr sciErr       = sciErrInit();
201     struct Attr
202     {
203     public:
204         int *piAddr;
205         int *piNbItemRow;
206         int *piColPos;
207         Attr() : piAddr(NULL), piNbItemRow(NULL), piColPos(NULL) {}
208         ~Attr()
209         {
210             if (piNbItemRow)
211             {
212                 FREE(piNbItemRow);
213             }
214             if (piColPos)
215             {
216                 FREE(piColPos);
217             }
218             if (piAddr)
219             {
220                 FREE(piAddr);
221             }
222         }
223     };
224     struct Attr attr;
225     sciErr = getVarAddressFromName(_pvCtx, _pstName, &attr.piAddr);
226     if (sciErr.iErr)
227     {
228         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_BOOLEAN_SPARSE, _("%s: Unable to get variable \"%s\""), "readNamedBooleanSparseMatrix", _pstName);
229         return sciErr;
230     }
231
232     sciErr = getBooleanSparseMatrix(_pvCtx, attr.piAddr, _piRows, _piCols, _piNbItem, &attr.piNbItemRow, &attr.piColPos);
233     if (sciErr.iErr)
234     {
235         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_BOOLEAN_SPARSE, _("API_ERROR_READ_NAMED_BOOLEAN_SPARSE"));
236         return sciErr;
237     }
238
239     if (_piNbItemRow == NULL)
240     {
241         return sciErr;
242     }
243
244     memcpy(_piNbItemRow, attr.piNbItemRow, *_piRows * sizeof(int));
245
246     if (_piColPos == NULL)
247     {
248         return sciErr;
249     }
250
251     memcpy(_piColPos, attr.piColPos, *_piNbItem * sizeof(int));
252     return sciErr;
253 }
254 /*--------------------------------------------------------------------------*/
255 int isBooleanSparseType(void* _pvCtx, int* _piAddress)
256 {
257     return checkVarType(_pvCtx, _piAddress, sci_boolean_sparse);
258 }
259 /*--------------------------------------------------------------------------*/
260 int isNamedBooleanSparseType(void* _pvCtx, const char* _pstName)
261 {
262     return checkNamedVarType(_pvCtx, _pstName, sci_boolean_sparse);
263 }
264 /*--------------------------------------------------------------------------*/
265 int getAllocatedBooleanSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos)
266 {
267     SciErr sciErr = sciErrInit();
268     int* piNbItemRow    = NULL;
269     int* piColPos                       = NULL;
270
271     sciErr = getBooleanSparseMatrix(_pvCtx, _piAddress, _piRows, _piCols, _piNbItem, &piNbItemRow, &piColPos);
272     if (sciErr.iErr)
273     {
274         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_BOOLEAN_SPARSE, _("%s: Unable to get argument #%d"), "getAllocatedBooleanSparseMatrix", getRhsFromAddress(_pvCtx, _piAddress));
275         printError(&sciErr, 0);
276         FREE(piNbItemRow);
277         FREE(piColPos);
278         return sciErr.iErr;
279     }
280
281     *_piNbItemRow               = (int*)MALLOC(sizeof(int) **_piRows);
282     memcpy(*_piNbItemRow, piNbItemRow, sizeof(int) **_piRows);
283
284     *_piColPos                  = (int*)MALLOC(sizeof(int) **_piNbItem);
285     memcpy(*_piColPos, piColPos, sizeof(int) **_piNbItem);
286
287     FREE(piNbItemRow);
288     FREE(piColPos);
289     return 0;
290 }
291 /*--------------------------------------------------------------------------*/
292 int getNamedAllocatedBooleanSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos)
293 {
294     SciErr sciErr = sciErrInit();
295     sciErr = readNamedBooleanSparseMatrix(_pvCtx, _pstName, _piRows, _piCols, _piNbItem, NULL, NULL);
296     if (sciErr.iErr)
297     {
298         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_ALLOC_BOOLEAN_SPARSE, _("%s: Unable to get argument \"%s\""), "getNamedAllocatedBooleanSparseMatrix", _pstName);
299         printError(&sciErr, 0);
300         return sciErr.iErr;
301     }
302
303     *_piNbItemRow               = (int*)MALLOC(sizeof(int) **_piRows);
304     *_piColPos                  = (int*)MALLOC(sizeof(int) **_piNbItem);
305
306     sciErr = readNamedBooleanSparseMatrix(_pvCtx, _pstName, _piRows, _piCols, _piNbItem, *_piNbItemRow, *_piColPos);
307     if (sciErr.iErr)
308     {
309         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_ALLOC_BOOLEAN_SPARSE, _("%s: Unable to get argument \"%s\""), "getNamedAllocatedBooleanSparseMatrix", _pstName);
310         printError(&sciErr, 0);
311         return sciErr.iErr;
312     }
313
314     return 0;
315 }
316 /*--------------------------------------------------------------------------*/
317 void freeAllocatedBooleanSparse(int* _piNbItemRow, int* _piColPos)
318 {
319     FREE(_piNbItemRow);
320     FREE(_piColPos);
321 }