2025678c357a5d58f76df159528e632a9803e78d
[scilab.git] / scilab / modules / matio / src / c / GetSparseVariable.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent COUVERT
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-en.txt
10  *
11  */
12
13 #include "GetMatlabVariable.h"
14 #include "stack-c.h"
15 #include "api_scilab.h"
16
17 #define MATIO_ERROR if(_SciErr.iErr) \
18     {                                \
19       printError(&_SciErr, 0);       \
20       return 0;                      \
21     }
22
23 matvar_t *GetSparseVariable(int iVar, const char *name, int * parent, int item_position)
24 {
25     int K = 0;
26     int rank = 0;
27     int *dims = NULL;
28     double *data = NULL;
29     matvar_t *createdVar = NULL;
30     sparse_t *sparseData = NULL;
31     SciSparse scilabSparse;
32     int *colIndexes = NULL;
33     int *rowIndexes = NULL;
34     int * var_addr = NULL;
35     int * item_addr = NULL;
36     int var_type;
37     SciErr _SciErr;
38
39     if (parent == NULL)
40     {
41         _SciErr = getVarAddressFromPosition(pvApiCtx, iVar, &var_addr);
42         MATIO_ERROR;
43         _SciErr = getVarType(pvApiCtx, var_addr, &var_type);
44         MATIO_ERROR;
45     }
46     else
47     {
48         _SciErr = getListItemAddress(pvApiCtx, parent, item_position, &item_addr);
49         MATIO_ERROR;
50         _SciErr = getVarType(pvApiCtx, item_addr, &var_type);
51         MATIO_ERROR;
52     }
53
54     if (var_type == sci_sparse)
55     {
56         sparseData = (sparse_t*) MALLOC(sizeof(sparse_t));
57         if (sparseData == NULL)
58         {
59             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
60             return FALSE;
61         }
62
63         rank = 2;
64         if ((dims = (int*) MALLOC (sizeof(int) * rank)) == NULL)
65         {
66             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
67             free(sparseData);
68             return NULL;
69         }
70
71         if (isVarComplex(pvApiCtx, var_addr))
72         {
73             if (parent == NULL)
74             {
75                 getAllocatedComplexSparseMatrix(pvApiCtx, var_addr, &dims[1], &dims[0],
76                                                 &scilabSparse.nel, &scilabSparse.mnel,
77                                                 &scilabSparse.icol, &scilabSparse.R,
78                                                 &scilabSparse.I);
79             }
80             else
81             {
82                 _SciErr = getSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
83                                                 &scilabSparse.nel, NULL, NULL, NULL);
84                 scilabSparse.mnel = (int *)MALLOC(dims[1] * sizeof(int));
85                 if (scilabSparse.mnel == NULL)
86                 {
87                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
88
89                     FREE(scilabSparse.mnel);
90
91                     return FALSE;
92                 }
93                 scilabSparse.icol = (int *)MALLOC(scilabSparse.nel * sizeof(int));
94                 if (scilabSparse.icol == NULL)
95                 {
96                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
97
98                     FREE(scilabSparse.mnel);
99                     FREE(scilabSparse.icol);
100
101                     return FALSE;
102                 }
103                 scilabSparse.R    = (double *)MALLOC(scilabSparse.nel * sizeof(double));
104                 if (scilabSparse.R == NULL)
105                 {
106                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
107
108                     FREE(scilabSparse.mnel);
109                     FREE(scilabSparse.icol);
110                     FREE(scilabSparse.R);
111
112                     return FALSE;
113                 }
114                 scilabSparse.I    = (double *)MALLOC(scilabSparse.nel * sizeof(double));
115                 if (scilabSparse.I == NULL)
116                 {
117                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
118
119                     FREE(scilabSparse.mnel);
120                     FREE(scilabSparse.icol);
121                     FREE(scilabSparse.R);
122                     FREE(scilabSparse.I);
123
124                     return FALSE;
125                 }
126                 _SciErr = getComplexSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
127                                                        &scilabSparse.nel, &scilabSparse.mnel,
128                                                        &scilabSparse.icol, &scilabSparse.R, &scilabSparse.I);
129             }
130
131             scilabSparse.it = 1;
132
133         }
134         else
135         {
136             if (parent == NULL)
137             {
138                 getAllocatedSparseMatrix(pvApiCtx, var_addr, &dims[1], &dims[0],
139                                          &scilabSparse.nel, &scilabSparse.mnel,
140                                          &scilabSparse.icol, &scilabSparse.R);
141             }
142             else
143             {
144                 _SciErr = getSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
145                                                 &scilabSparse.nel, NULL, NULL, NULL);
146                 scilabSparse.mnel = (int *)MALLOC(dims[1] * sizeof(int));
147                 if (scilabSparse.mnel == NULL)
148                 {
149                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
150
151                     FREE(scilabSparse.mnel);
152
153                     return FALSE;
154                 }
155                 scilabSparse.icol = (int *)MALLOC(scilabSparse.nel * sizeof(int));
156                 if (scilabSparse.icol == NULL)
157                 {
158                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
159
160                     FREE(scilabSparse.mnel);
161                     FREE(scilabSparse.icol);
162
163                     return FALSE;
164                 }
165                 scilabSparse.R    = (double *)MALLOC(scilabSparse.nel * sizeof(double));
166                 if (scilabSparse.R == NULL)
167                 {
168                     Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
169
170                     FREE(scilabSparse.mnel);
171                     FREE(scilabSparse.icol);
172                     FREE(scilabSparse.R);
173
174                     return FALSE;
175                 }
176                 _SciErr = getSparseMatrixInList(pvApiCtx, parent, item_position, &dims[1], &dims[0],
177                                                 &scilabSparse.nel, &scilabSparse.mnel,
178                                                 &scilabSparse.icol, &scilabSparse.R);
179             }
180
181             scilabSparse.it = 0;
182         }
183
184         scilabSparse.m = dims[1];
185         scilabSparse.n = dims[0];
186
187         /* colIndexes = (int*) MALLOC(sizeof(int) *  (scilabSparse.nel + 1));  */
188         colIndexes = (int*) MALLOC(sizeof(int) *  (scilabSparse.m + 1));
189         if (colIndexes == NULL)
190         {
191             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
192
193             if (scilabSparse.it)
194             {
195                 freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
196             }
197             else
198             {
199                 freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
200             }
201
202             return FALSE;
203         }
204
205         colIndexes[0] = 0;
206         /* for (K=0; K<scilabSparse.nel; K++) */
207         for (K = 0; K < scilabSparse.m; K++)
208         {
209             colIndexes[K + 1] = colIndexes[K] + scilabSparse.mnel[K];
210         }
211
212         rowIndexes = (int*) MALLOC(sizeof(int) *  scilabSparse.nel);
213         if (rowIndexes == NULL)
214         {
215             Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
216             free(colIndexes);
217
218             if (scilabSparse.it)
219             {
220                 freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
221             }
222             else
223             {
224                 freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
225             }
226
227             return FALSE;
228         }
229
230         for (K = 0; K < scilabSparse.nel; K++)
231         {
232             rowIndexes[K] = scilabSparse.icol[K] - 1;
233         }
234
235         if (scilabSparse.it == 0) /* Real sparse */
236         {
237             if ((data = (double*) MALLOC(sizeof(double) * scilabSparse.nel)) == NULL)
238             {
239                 Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
240                 free(rowIndexes);
241                 free(colIndexes);
242                 if (scilabSparse.it)
243                 {
244                     freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
245                 }
246                 else
247                 {
248                     freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
249                 }
250
251                 return 0;
252             }
253
254             for (K = 0; K < scilabSparse.nel; K++)
255             {
256                 data[K] = scilabSparse.R[K];
257             }
258         }
259         else
260         {
261             if ((data = (double*) MALLOC(2 * sizeof(double) * scilabSparse.nel)) == NULL)
262             {
263                 Scierror(999, _("%s: No more memory.\n"), "GetSparseVariable");
264
265                 if (scilabSparse.it)
266                 {
267                     freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
268                 }
269                 else
270                 {
271                     freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
272                 }
273                 free(rowIndexes);
274                 free(colIndexes);
275                 return FALSE;
276             }
277
278             for (K = 0; K < scilabSparse.nel; K++)
279             {
280                 data[K] = scilabSparse.R[K];
281             }
282
283             for (K = 0; K < scilabSparse.nel; K++)
284             {
285                 data[K + scilabSparse.nel] = scilabSparse.I[K];
286             }
287         }
288
289         /* Create Matlab Sparse matrix data */
290         sparseData->nzmax = scilabSparse.nel;
291         sparseData->nir   = scilabSparse.nel;
292         sparseData->ir    = rowIndexes;
293         /* sparseData->njc   = scilabSparse.nel + 1; */
294         sparseData->njc   = scilabSparse.m + 1;
295         sparseData->jc    = colIndexes;
296         sparseData->ndata = scilabSparse.nel;
297         sparseData->data  = (void*) data;
298
299         if (scilabSparse.it == 0)
300         {
301             createdVar = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, rank, dims, sparseData, 0 | MEM_CONSERVE);
302         }
303         else
304         {
305             createdVar = Mat_VarCreate(name, MAT_C_SPARSE, MAT_T_DOUBLE, rank, dims, sparseData, MAT_F_COMPLEX | MEM_CONSERVE);
306             if (data)
307             {
308                 FREE(data);
309             }
310         }
311
312         if (dims)
313         {
314             FREE(dims);
315         }
316     }
317     else
318     {
319         Scierror(999, _("%s: Wrong type for first input argument: Sparse matrix expected.\n"), "GetSparseVariable");
320     }
321
322     if (scilabSparse.it)
323     {
324         freeAllocatedComplexSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R, scilabSparse.I);
325     }
326     else
327     {
328         freeAllocatedSparseMatrix(scilabSparse.mnel, scilabSparse.icol, scilabSparse.R);
329     }
330
331     return createdVar;
332 }