d1418634ca59128463eec6355235d3e30b521fd2
[scilab.git] / scilab / modules / api_scilab / src / cpp / api_stack_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 #include "sparse.hxx"
19 #include "context.hxx"
20 #include "gatewaystruct.hxx"
21
22 extern "C"
23 {
24 #include <string.h>
25 #include "elem_common.h"
26 #include "api_scilab.h"
27 #include "api_internal_common.h"
28 #include "api_internal_sparse.h"
29 #include "localization.h"
30 #include "sci_malloc.h"
31 #include "call_scilab.h"
32 }
33
34 static int getCommonAllocatedSparseMatrix(void* _pvCtx, int* _piAddress, int _iComplex, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg);
35 static int getCommonNamedAllocatedSparseMatrix(void* _pvCtx, const char* _pstName, int _iComplex, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg);
36
37
38 //internal sparse functions
39 SciErr getSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal)
40 {
41     return getCommonSparseMatrix(_pvCtx, _piAddress, 0, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
42 }
43
44 SciErr getComplexSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
45 {
46     return getCommonSparseMatrix(_pvCtx, _piAddress, 1, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
47 }
48
49 SciErr getCommonSparseMatrix(void* _pvCtx, int* _piAddress, int _iComplex, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
50 {
51     SciErr sciErr = sciErrInit();
52     int iPos = 0;
53     int iType = 0;
54
55     if (_piAddress == NULL)
56     {
57         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), _iComplex ? "getComplexSparseMatrix" : "getSparseMatrix");
58         return sciErr;
59     }
60
61     sciErr = getVarType(_pvCtx, _piAddress, &iType);
62     if (sciErr.iErr)
63     {
64         addErrorMessage(&sciErr, API_ERROR_GET_SPARSE, _("%s: Unable to get argument #%d"), _iComplex ? "getComplexSparseMatrix" : "getSparseMatrix", getRhsFromAddress(_pvCtx, _piAddress));
65         return sciErr;
66     }
67
68     if (iType != sci_sparse)
69     {
70         addErrorMessage(&sciErr, API_ERROR_INVALID_TYPE, _("%s: Invalid argument type, %s expected"), _iComplex ? "getComplexSparseMatrix" : "getSparseMatrix", _("sparse matrix"));
71         return sciErr;
72     }
73
74     if (isVarComplex(_pvCtx, _piAddress) != _iComplex)
75     {
76         addErrorMessage(&sciErr, API_ERROR_INVALID_COMPLEXITY, _("%s: Bad call to get a non complex matrix"), _iComplex ? "getComplexSparseMatrix" : "getSparseMatrix");
77         return sciErr;
78     }
79
80
81     sciErr = getVarDimension(_pvCtx, _piAddress, _piRows, _piCols);
82     if (sciErr.iErr)
83     {
84         addErrorMessage(&sciErr, API_ERROR_GET_SPARSE, _("%s: Unable to get argument #%d"), _iComplex ? "getComplexSparseMatrix" : "getSparseMatrix", getRhsFromAddress(_pvCtx, _piAddress));
85         return sciErr;
86     }
87
88     types::Sparse* pS = ((types::InternalType*)_piAddress)->getAs<types::Sparse>();
89
90     *_piNbItem = (int)pS->nonZeros();
91
92     if (_piNbItemRow == NULL)
93     {
94         return sciErr;
95     }
96
97     //WARNING: leak memory, caller must free pointer
98     int* piNbItemRows = (int*)MALLOC(sizeof(int) **_piRows);
99     *_piNbItemRow = pS->getNbItemByRow(piNbItemRows);
100
101     if (_piColPos == NULL)
102     {
103         return sciErr;
104     }
105
106     //WARNING: leak memory, caller must free pointer
107     int* piColPos = (int*)MALLOC(sizeof(int) **_piNbItem);
108     *_piColPos = pS->getColPos(piColPos);
109
110     if (_pdblReal == NULL)
111     {
112         return sciErr;
113     }
114
115     //WARNING: leak memory, caller must free pointers
116     double* pR = (double*)MALLOC(sizeof(double) **_piNbItem);
117     double* pI = (double*)MALLOC(sizeof(double) **_piNbItem);
118     pS->outputValues(pR, pI);
119
120     *_pdblReal = pR;
121
122     if (_iComplex == 1 && _pdblImg != NULL)
123     {
124         *_pdblImg = pI;
125     }
126     else
127     {
128         FREE(pI);
129     }
130
131     return sciErr;
132 }
133
134 SciErr allocSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal)
135 {
136     return allocCommonSparseMatrix(_pvCtx, _iVar, 0, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
137 }
138
139 SciErr allocComplexSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
140 {
141     return allocCommonSparseMatrix(_pvCtx, _iVar, 1, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
142 }
143
144 SciErr allocCommonSparseMatrix(void* _pvCtx, int _iVar, int _iComplex, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
145 {
146     SciErr sciErr = sciErrInit();
147     // We cant rewrite this function in Scilab 6
148     // because sparses are not stored like scilab 5.
149     // We cant return pointer to _piNbItemRow and
150     // _piColPos and let user fill it.
151     return sciErr;
152 }
153
154 SciErr fillCommonSparseMatrix(void* _pvCtx, int **_piAddress, int _iComplex, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos, const double* _pdblReal, const double* _pdblImg, int* _piTotalSize)
155 {
156     SciErr sciErr = sciErrInit();
157
158     if (_piAddress == NULL)
159     {
160         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "fillCommonSparseMatrix");
161         return sciErr;
162     }
163
164     //convert to ij, val, dims format to call sparse constructor
165
166     //dims
167     types::Double* dims = new types::Double(1, 2, false);
168     dims->get()[0] = (double)_iRows;
169     dims->get()[1] = (double)_iCols;
170
171     //ij
172     types::Double* ij = new types::Double(_iNbItem, 2);
173     double* pI = ij->get();
174     double* pJ = ij->get() + _iNbItem;
175
176     int idx = 0;
177     for (int i = 0; i < _iRows; i++)
178     {
179         for (int j = 0; j < _piNbItemRow[i]; j++)
180         {
181             pI[idx] = i + 1;
182             pJ[idx] = *_piColPos++;
183             ++idx;
184         }
185     }
186
187     types::Double* val = new types::Double(_iNbItem, 1, _iComplex == 1);
188     double* pR = val->get();
189     if (_iComplex)
190     {
191         double* pI = val->getImg();
192         for (int i = 0; i < _iNbItem; ++i)
193         {
194             pR[i] = _pdblReal[i];
195             pI[i] = _pdblImg[i];
196         }
197     }
198     else
199     {
200         for (int i = 0; i < _iNbItem; ++i)
201         {
202             pR[i] = _pdblReal[i];
203         }
204     }
205
206     types::Sparse* pSparse = new types::Sparse(*val, *ij, *dims);
207     delete dims;
208     delete val;
209     delete ij;
210
211     *_piAddress = (int*)pSparse;
212     *_piTotalSize = (int)pSparse->nonZeros();
213
214     return sciErr;
215 }
216
217 SciErr createSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos, const double* _pdblReal)
218 {
219     return createCommonSparseMatrix(_pvCtx, _iVar, 0, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
220 }
221
222 SciErr createComplexSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos, const double* _pdblReal, const double* _pdblImg)
223 {
224     return createCommonSparseMatrix(_pvCtx, _iVar, 1, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
225 }
226
227 SciErr createCommonSparseMatrix(void* _pvCtx, int _iVar, int _iComplex, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos, const double* _pdblReal, const double* _pdblImg)
228 {
229     SciErr sciErr = sciErrInit();
230
231     if (_iRows == 0 && _iCols == 0)
232     {
233         double dblReal = 0;
234         sciErr = createMatrixOfDouble(_pvCtx, _iVar, 0, 0, &dblReal);
235         if (sciErr.iErr)
236         {
237             addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
238         }
239         return sciErr;
240     }
241
242     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
243     types::InternalType** out = pStr->m_pOut;
244
245     int iTotalSize = 0;
246     types::Sparse* pSparse = NULL;
247     sciErr = fillCommonSparseMatrix(_pvCtx, (int**)&pSparse, _iComplex, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg, &iTotalSize);
248     if (pSparse == NULL)
249     {
250         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_SPARSE, _("%s: Unable to create variable in Scilab memory"), _iComplex ? "createComplexSparseMatrix" : "createSparseMatrix");
251         return sciErr;
252     }
253
254     int rhs = _iVar - *getNbInputArgument(_pvCtx);
255     out[rhs - 1] = pSparse;
256
257     return sciErr;
258 }
259
260 SciErr createNamedSparseMatrix(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos, const double* _pdblReal)
261 {
262     return createCommonNamedSparseMatrix(_pvCtx, _pstName, 0, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
263 }
264
265 SciErr createNamedComplexSparseMatrix(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos, const double* _pdblReal, const double* _pdblImg)
266 {
267     return createCommonNamedSparseMatrix(_pvCtx, _pstName, 1, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
268 }
269
270 SciErr createCommonNamedSparseMatrix(void* _pvCtx, const char* _pstName, int _iComplex, int _iRows, int _iCols, int _iNbItem, const int* _piNbItemRow, const int* _piColPos, const double* _pdblReal, const double* _pdblImg)
271 {
272     SciErr sciErr = sciErrInit();
273
274     // check variable name
275     if (checkNamedVarFormat(_pvCtx, _pstName) == 0)
276     {
277         addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Invalid variable name: %s."), "createCommonNamedMatrixOfPoly", _pstName);
278         return sciErr;
279     }
280
281     //return named empty matrix
282     if (_iRows == 0 && _iCols == 0)
283     {
284         double dblReal = 0;
285         sciErr = createNamedMatrixOfDouble(_pvCtx, _pstName, 0, 0, &dblReal);
286         if (sciErr.iErr)
287         {
288             addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createNamedEmptyMatrix");
289         }
290         return sciErr;
291     }
292
293     if (!checkNamedVarFormat(_pvCtx, _pstName))
294     {
295         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createCommonNamedSparseMatrix", _pstName);
296         return sciErr;
297     }
298
299     int iTotalSize = 0;
300     types::Sparse* pSparse = NULL;
301     sciErr = fillCommonSparseMatrix(_pvCtx, (int**)&pSparse, _iComplex, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg, &iTotalSize);
302     if (pSparse == NULL)
303     {
304         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_SPARSE, _("%s: Unable to create %s named \"%s\""), _iComplex ? "createNamedComplexSparseMatrix" : "createNamedSparseMatrix", _("sparse matrix"), _pstName);
305         return sciErr;
306     }
307
308
309     wchar_t* pwstName = to_wide_string(_pstName);
310     symbol::Context* ctx = symbol::Context::getInstance();
311     symbol::Symbol sym = symbol::Symbol(pwstName);
312     FREE(pwstName);
313     if (ctx->isprotected(sym) == false)
314     {
315         ctx->put(sym, pSparse);
316     }
317     else
318     {
319         delete pSparse;
320         addErrorMessage(&sciErr, API_ERROR_REDEFINE_PERMANENT_VAR, _("Redefining permanent variable.\n"));
321     }
322     return sciErr;
323 }
324
325 SciErr readNamedSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int* _piNbItemRow, int* _piColPos, double* _pdblReal)
326 {
327     return readCommonNamedSparseMatrix(_pvCtx, _pstName, 0, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
328 }
329
330 SciErr readNamedComplexSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int* _piNbItemRow, int* _piColPos, double* _pdblReal, double* _pdblImg)
331 {
332     return readCommonNamedSparseMatrix(_pvCtx, _pstName, 1, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
333 }
334
335 SciErr readCommonNamedSparseMatrix(void* _pvCtx, const char* _pstName, int _iComplex, int* _piRows, int* _piCols, int* _piNbItem, int* _piNbItemRow, int* _piColPos, double* _pdblReal, double* _pdblImg)
336 {
337     int* piAddr = NULL;
338     int* piNbItemRow = 0;
339     int* piColPos = 0;
340     int iOne = 1;
341
342     double* pdblReal = NULL;
343     double* pdblImg = NULL;
344
345     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
346     if (sciErr.iErr)
347     {
348         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_SPARSE, _("%s: Unable to get variable \"%s\""), _iComplex ? "readNamedComplexSparseMatrix" : "readNamedSparseMatrix", _pstName);
349         return sciErr;
350     }
351
352     if (_iComplex == 1)
353     {
354         sciErr = getComplexSparseMatrix(_pvCtx, piAddr, _piRows, _piCols, _piNbItem, &piNbItemRow, &piColPos, &pdblReal, &pdblImg);
355     }
356     else
357     {
358         sciErr = getSparseMatrix(_pvCtx, piAddr, _piRows, _piCols, _piNbItem, &piNbItemRow, &piColPos, &pdblReal);
359     }
360
361     if (sciErr.iErr)
362     {
363         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_SPARSE, _("%s: Unable to get variable \"%s\""), _iComplex ? "readNamedComplexSparseMatrix" : "readNamedSparseMatrix", _pstName);
364         return sciErr;
365     }
366
367     if (_piNbItemRow == NULL)
368     {
369         return sciErr;
370     }
371
372     memcpy(_piNbItemRow, piNbItemRow, *_piRows * sizeof(int));
373
374     if (_piColPos == NULL)
375     {
376         return sciErr;
377     }
378
379     memcpy(_piColPos, piColPos, *_piNbItem * sizeof(int));
380
381
382     if (_pdblReal == NULL)
383     {
384         return sciErr;
385     }
386
387     C2F(dcopy)(_piNbItem, pdblReal, &iOne, _pdblReal, &iOne);
388
389     if (_iComplex && _pdblImg)
390     {
391         C2F(dcopy)(_piNbItem, pdblImg, &iOne, _pdblImg, &iOne);
392     }
393
394     return sciErr;
395 }
396
397 /* shortcut functions */
398
399 /*--------------------------------------------------------------------------*/
400 int isSparseType(void* _pvCtx, int* _piAddress)
401 {
402     return checkVarType(_pvCtx, _piAddress, sci_sparse);
403 }
404 /*--------------------------------------------------------------------------*/
405 int isNamedSparseType(void* _pvCtx, const char* _pstName)
406 {
407     return checkNamedVarType(_pvCtx, _pstName, sci_sparse);
408 }
409 /*--------------------------------------------------------------------------*/
410 int getAllocatedSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal)
411 {
412     return getCommonAllocatedSparseMatrix(_pvCtx, _piAddress, 0, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
413 }
414 /*--------------------------------------------------------------------------*/
415 int getAllocatedComplexSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
416 {
417     return getCommonAllocatedSparseMatrix(_pvCtx, _piAddress, 1, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
418 }
419 /*--------------------------------------------------------------------------*/
420 static int getCommonAllocatedSparseMatrix(void* _pvCtx, int* _piAddress, int _iComplex, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
421 {
422     int* piNbItemRow = NULL;
423     int* piColPos = NULL;
424     int iOne = 1;
425     double* pdblReal = NULL;
426     double* pdblImg = NULL;
427
428     SciErr sciErr = getCommonSparseMatrix(_pvCtx, _piAddress, _iComplex, _piRows, _piCols, _piNbItem, &piNbItemRow, &piColPos, &pdblReal, &pdblImg);
429     if (sciErr.iErr)
430     {
431         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_SPARSE, _("%s: Unable to get argument #%d"), _iComplex ? "getAllocatedComplexSparseMatrix" : "getAllocatedSparseMatrix", getRhsFromAddress(_pvCtx, _piAddress));
432         printError(&sciErr, 0);
433         return sciErr.iErr;
434     }
435
436     *_piNbItemRow = (int*)MALLOC(sizeof(int) **_piRows);
437     memcpy(*_piNbItemRow, piNbItemRow, sizeof(int) **_piRows);
438
439     *_piColPos = (int*)MALLOC(sizeof(int) **_piNbItem);
440     memcpy(*_piColPos, piColPos, sizeof(int) **_piNbItem);
441
442     *_pdblReal = (double*)MALLOC(sizeof(double) **_piNbItem);
443     C2F(dcopy)(_piNbItem, pdblReal, &iOne, *_pdblReal, &iOne);
444
445     FREE(piNbItemRow);
446     FREE(piColPos);
447     FREE(pdblReal);
448
449     if (_iComplex)
450     {
451         *_pdblImg = (double*)MALLOC(sizeof(double) **_piNbItem);
452         C2F(dcopy)(_piNbItem, pdblImg, &iOne, *_pdblImg, &iOne);
453         FREE(pdblImg);
454     }
455
456
457     return 0;
458 }
459 /*--------------------------------------------------------------------------*/
460 int getNamedAllocatedSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal)
461 {
462     return getCommonNamedAllocatedSparseMatrix(_pvCtx, _pstName, 0, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
463 }
464 /*--------------------------------------------------------------------------*/
465 int getNamedAllocatedComplexSparseMatrix(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
466 {
467     return getCommonNamedAllocatedSparseMatrix(_pvCtx, _pstName, 1, _piRows, _piCols, _piNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
468 }
469 /*--------------------------------------------------------------------------*/
470 static int getCommonNamedAllocatedSparseMatrix(void* _pvCtx, const char* _pstName, int _iComplex, int* _piRows, int* _piCols, int* _piNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
471 {
472     SciErr sciErr = readCommonNamedSparseMatrix(_pvCtx, _pstName, _iComplex, _piRows, _piCols, _piNbItem, NULL, NULL, NULL, NULL);
473     if (sciErr.iErr)
474     {
475         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_ALLOC_SPARSE, _("%s: Unable to get argument \"%s\""), _iComplex ? "getNamedAllocatedComplexSparseMatrix" : "getNamedAllocatedSparseMatrix", _pstName);
476         printError(&sciErr, 0);
477         return sciErr.iErr;
478     }
479
480     *_piNbItemRow = (int*)MALLOC(sizeof(int) **_piRows);
481     *_piColPos = (int*)MALLOC(sizeof(int) **_piNbItem);
482
483     *_pdblReal = (double*)MALLOC(sizeof(double) **_piNbItem);
484     if (_iComplex)
485     {
486         *_pdblImg = (double*)MALLOC(sizeof(double) **_piNbItem);
487     }
488
489     sciErr = readCommonNamedSparseMatrix(_pvCtx, _pstName, _iComplex, _piRows, _piCols, _piNbItem, *_piNbItemRow, *_piColPos, *_pdblReal, *_pdblImg);
490     if (sciErr.iErr)
491     {
492         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_ALLOC_SPARSE, _("%s: Unable to get argument \"%s\""), _iComplex ? "getNamedAllocatedComplexSparseMatrix" : "getNamedAllocatedSparseMatrix", _pstName);
493         printError(&sciErr, 0);
494         return sciErr.iErr;
495     }
496
497     return 0;
498 }
499 /*--------------------------------------------------------------------------*/
500 void freeAllocatedSparseMatrix(int* _piNbItemRows, int* _piColPos, double* _pdblReal)
501 {
502     FREE(_piNbItemRows);
503     FREE(_piColPos);
504     FREE(_pdblReal);
505 }
506 /*--------------------------------------------------------------------------*/
507 void freeAllocatedComplexSparseMatrix(int* _piNbItemRows, int* _piColPos, double* _pdblReal, double* _pdblImg)
508 {
509     freeAllocatedSparseMatrix(_piNbItemRows, _piColPos, _pdblReal);
510     FREE(_pdblImg);
511 }
512 /*--------------------------------------------------------------------------*/